diff --git a/package-lock.json b/package-lock.json index c29656a78..9c8b334f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4673,7 +4673,7 @@ "bootstrap-select": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/bootstrap-select/-/bootstrap-select-1.12.2.tgz", - "integrity": "sha1-WNCVs/1YSzFEOGb745tv3U5OEqQ=", + "integrity": "sha512-Fj1VstB55LigEEYQb6ZOi/ok+uaqnslRxS8Qo9Q+F46WWDhhXAeNpjBhjEMlxQjPs9yqYZf2hf/mxVRWab8sow==", "optional": true, "requires": { "jquery": ">=1.8" @@ -4682,7 +4682,7 @@ "bootstrap-slider": { "version": "9.10.0", "resolved": "https://registry.npmjs.org/bootstrap-slider/-/bootstrap-slider-9.10.0.tgz", - "integrity": "sha1-EQPWvADPv6jPyaJZmrUYxVZD2j8=", + "integrity": "sha512-a9MtENtt4r3ttPW5mpIpOFmCaIsm37EGukOgw5cfHlxKvsUSN8AN9JtwKrKuqgEnxs86kUSsMvMn8kqewMorKw==", "optional": true }, "bootstrap-slider-without-jquery": { @@ -4693,13 +4693,13 @@ "bootstrap-switch": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/bootstrap-switch/-/bootstrap-switch-3.3.4.tgz", - "integrity": "sha1-cOCusqh3wNx2aZHeEI4hcPwpov8=", + "integrity": "sha512-7YQo+Ir6gCUqC36FFp1Zvec5dRF/+obq+1drMtdIMi9Xc84Kx63Evi0kdcp4HfiGsZpiz6IskyYDNlSKcxsL7w==", "optional": true }, "bootstrap-touchspin": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/bootstrap-touchspin/-/bootstrap-touchspin-3.1.1.tgz", - "integrity": "sha1-l3nerHKq9Xfl52K4USx0fIcdlZc=", + "integrity": "sha512-o5pgzdr8Ma5hQKS3JE1uNq/jkx8qCG+KhJXSlvYCmX2wTxva2sS2Kq3idGN+tP5e1bZJQgkbqwP9TdEEx+R+6Q==", "optional": true }, "boxen": { @@ -6307,7 +6307,7 @@ "datatables.net-colreorder-bs": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/datatables.net-colreorder-bs/-/datatables.net-colreorder-bs-1.3.3.tgz", - "integrity": "sha1-Op3LCN7r612FQHlZHgbkk615OlM=", + "integrity": "sha512-+DPim/DhbSIqr2rhRvYNrAMFNZgl372PiKEAv5YeyjYMzc8+6kX8Vinpb3Bg0PDgEdPqEWqJ6H18pBCKhXppgg==", "optional": true, "requires": { "datatables.net-bs": ">=1.10.9", @@ -6834,7 +6834,7 @@ "drmonty-datatables-colvis": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/drmonty-datatables-colvis/-/drmonty-datatables-colvis-1.1.2.tgz", - "integrity": "sha1-lque37SGQ8wu3aP4e4iTPN7oEnw=", + "integrity": "sha512-1kL4fbsBEkQQTl83eQ8G/vRGcCiM6Hn3O8Tp473tG4YSsBDcxETDDSxb8qC+fQjHZ3jUCptWj3lG/L8rI6NBNw==", "optional": true, "requires": { "jquery": ">=1.7.0" @@ -9425,12 +9425,12 @@ "font-awesome": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", - "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" + "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==" }, "font-awesome-sass": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/font-awesome-sass/-/font-awesome-sass-4.7.0.tgz", - "integrity": "sha1-TtppPpFQCc4Asijglk3F7Km8NOE=", + "integrity": "sha512-apO2Nw3XP/Zv7fLxa+MnPnvJ/GdkH6qWrLrtN5oQrFL7RPprzHKROjN94jgyoxM+T7PQBhY9F/SwOKbBaLyXxg==", "optional": true }, "for-in": { @@ -9917,7 +9917,7 @@ "google-code-prettify": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/google-code-prettify/-/google-code-prettify-1.0.5.tgz", - "integrity": "sha1-n0d/Ik2/piNy5e+AOn4VdBBAAIQ=", + "integrity": "sha512-Y47Bw63zJKCuqTuhTZC1ct4e/0ADuMssxXhnrP8QHq71tE2aYBKG6wQwXr8zya0zIUd0mKN3XTlI5AME4qm6NQ==", "optional": true }, "got": { @@ -12957,7 +12957,7 @@ "jquery-match-height": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/jquery-match-height/-/jquery-match-height-0.7.2.tgz", - "integrity": "sha1-+NnzulMU2qsQnPB0CGdL4gS+Xw4=", + "integrity": "sha512-qSyC0GBc4zUlgBcxfyyumJSVUm50T6XuJEIz59cKaI28VXMUT95mZ6KiIjhMIMbG8IiJhh65FtQO1XD42TAcwg==", "optional": true }, "js-levenshtein": { @@ -13612,6 +13612,11 @@ "yallist": "^2.1.2" } }, + "lucide-react": { + "version": "0.469.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.469.0.tgz", + "integrity": "sha512-28vvUnnKQ/dBwiCQtwJw7QauYnE7yd2Cyp4tTTJpvglX4EMpbflcdBgrgToX2j71B3YvugK/NH3BGUk+E/p/Fw==" + }, "lz-string": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", @@ -13998,7 +14003,7 @@ "moment-timezone": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.4.1.tgz", - "integrity": "sha1-gfWYw61eIs2teWtn7NjYjQ9bqgY=", + "integrity": "sha512-5cNPVUwaVJDCe9JM8m/qz17f9SkaI8rpnRUyDJi2K5HAd6EwhuQ3n5nLclZkNC/qJnomKgQH2TIu70Gy2dxFKA==", "optional": true, "requires": { "moment": ">= 2.6.0" @@ -15814,7 +15819,7 @@ "patternfly-bootstrap-combobox": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/patternfly-bootstrap-combobox/-/patternfly-bootstrap-combobox-1.1.7.tgz", - "integrity": "sha1-al48zRFwwhs8S0qhaKdBPh3btuE=", + "integrity": "sha512-6KptS6UnS8jOwLuqsjokiNUYjOf3G4bSahiSHhkQMdfvG0b4sZkUgOFWdMJ8zBXaZGVe8T324GQoXqiJdJxMuw==", "optional": true }, "patternfly-bootstrap-treeview": { diff --git a/package.json b/package.json index 70cf57b24..b027e0900 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@entando/app-builder", - "version": "7.3.0", + "version": "7.3.0-SNAPSHOT", "author": "Entando", "homepage": "https://github.com/entando/app-builder", "license": "MIT", @@ -30,6 +30,7 @@ "html-webpack-plugin": "^3.2.0", "keycloak-js": "^18.0.1", "lodash": "^4.17.21", + "lucide-react": "^0.469.0", "md5": "^2.3.0", "moment": "^2.22.1", "object-assign": "4.1.1", @@ -82,8 +83,8 @@ "lint": "eslint ./src", "coverage": "node scripts/test.js --env=jest-environment-jsdom-sixteen --coverage", "sass-lint": "sass-lint -v", - "precommit": "npm run lint && npm run sass-lint && npm run coverage", - "build-full": "npm run precommit && npm run import-plugins && node scripts/build.js", + + "start-openshift": "npm install -g serve && serve -l 8080 -s build", "analyze": "source-map-explorer build/static/js/main.*", "app-install": "node apps/install.js", diff --git a/public/entando-de-app/cmsresources/menu/app-builder-menu.umd.js b/public/entando-de-app/cmsresources/menu/app-builder-menu.umd.js new file mode 100644 index 000000000..8c5096c95 --- /dev/null +++ b/public/entando-de-app/cmsresources/menu/app-builder-menu.umd.js @@ -0,0 +1,486 @@ +var m6=Object.defineProperty,v6=Object.defineProperties;var g6=Object.getOwnPropertyDescriptors;var F0=Object.getOwnPropertySymbols;var y6=Object.prototype.hasOwnProperty,E6=Object.prototype.propertyIsEnumerable;var Zu=(X,Q,z)=>Q in X?m6(X,Q,{enumerable:!0,configurable:!0,writable:!0,value:z}):X[Q]=z,xt=(X,Q)=>{for(var z in Q||(Q={}))y6.call(Q,z)&&Zu(X,z,Q[z]);if(F0)for(var z of F0(Q))E6.call(Q,z)&&Zu(X,z,Q[z]);return X},B0=(X,Q)=>v6(X,g6(Q));var U0=(X,Q,z)=>(Zu(X,typeof Q!="symbol"?Q+"":Q,z),z),Yu=(X,Q,z)=>{if(!Q.has(X))throw TypeError("Cannot "+z)};var $0=(X,Q,z)=>(Yu(X,Q,"read from private field"),z?z.call(X):Q.get(X)),Ku=(X,Q,z)=>{if(Q.has(X))throw TypeError("Cannot add the same private member more than once");Q instanceof WeakSet?Q.add(X):Q.set(X,z)},z0=(X,Q,z,B)=>(Yu(X,Q,"write to private field"),B?B.call(X,z):Q.set(X,z),z);var j0=(X,Q,z)=>(Yu(X,Q,"access private method"),z);(function(X){typeof define=="function"&&define.amd?define(X):X()})(function(){var Ho,Oa,V0;"use strict";var X={},Q={exports:{}},z={},B={exports:{}},V={};/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Pr=Symbol.for("react.element"),G0=Symbol.for("react.portal"),W0=Symbol.for("react.fragment"),X0=Symbol.for("react.strict_mode"),Q0=Symbol.for("react.profiler"),Z0=Symbol.for("react.provider"),Y0=Symbol.for("react.context"),K0=Symbol.for("react.forward_ref"),J0=Symbol.for("react.suspense"),q0=Symbol.for("react.memo"),em=Symbol.for("react.lazy"),Ju=Symbol.iterator;function tm(e){return e===null||typeof e!="object"?null:(e=Ju&&e[Ju]||e["@@iterator"],typeof e=="function"?e:null)}var qu={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},ec=Object.assign,tc={};function Wn(e,t,n){this.props=e,this.context=t,this.refs=tc,this.updater=n||qu}Wn.prototype.isReactComponent={},Wn.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},Wn.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function nc(){}nc.prototype=Wn.prototype;function Ha(e,t,n){this.props=e,this.context=t,this.refs=tc,this.updater=n||qu}var Da=Ha.prototype=new nc;Da.constructor=Ha,ec(Da,Wn.prototype),Da.isPureReactComponent=!0;var rc=Array.isArray,oc=Object.prototype.hasOwnProperty,Fa={current:null},ic={key:!0,ref:!0,__self:!0,__source:!0};function ac(e,t,n){var r,o={},i=null,a=null;if(t!=null)for(r in t.ref!==void 0&&(a=t.ref),t.key!==void 0&&(i=""+t.key),t)oc.call(t,r)&&!ic.hasOwnProperty(r)&&(o[r]=t[r]);var l=arguments.length-2;if(l===1)o.children=n;else if(1>>1,T=R[q];if(0>>1;qo(F,D))yo(j,F)?(R[q]=j,R[y]=D,q=y):(R[q]=F,R[M]=D,q=M);else if(yo(j,D))R[q]=j,R[y]=D,q=y;else break e}}return L}function o(R,L){var D=R.sortIndex-L.sortIndex;return D!==0?D:R.id-L.id}if(typeof performance=="object"&&typeof performance.now=="function"){var i=performance;e.unstable_now=function(){return i.now()}}else{var a=Date,l=a.now();e.unstable_now=function(){return a.now()-l}}var s=[],u=[],c=1,m=null,p=3,g=!1,v=!1,S=!1,C=typeof setTimeout=="function"?setTimeout:null,d=typeof clearTimeout=="function"?clearTimeout:null,f=typeof setImmediate!="undefined"?setImmediate:null;typeof navigator!="undefined"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function h(R){for(var L=n(u);L!==null;){if(L.callback===null)r(u);else if(L.startTime<=R)r(u),L.sortIndex=L.expirationTime,t(s,L);else break;L=n(u)}}function w(R){if(S=!1,h(R),!v)if(n(s)!==null)v=!0,Nt(E);else{var L=n(u);L!==null&&De(w,L.startTime-R)}}function E(R,L){v=!1,S&&(S=!1,d(b),b=-1),g=!0;var D=p;try{for(h(L),m=n(s);m!==null&&(!(m.expirationTime>L)||R&&!Ee());){var q=m.callback;if(typeof q=="function"){m.callback=null,p=m.priorityLevel;var T=q(m.expirationTime<=L);L=e.unstable_now(),typeof T=="function"?m.callback=T:m===n(s)&&r(s),h(L)}else r(s);m=n(s)}if(m!==null)var I=!0;else{var M=n(u);M!==null&&De(w,M.startTime-L),I=!1}return I}finally{m=null,p=D,g=!1}}var _=!1,A=null,b=-1,Y=5,H=-1;function Ee(){return!(e.unstable_now()-HR||125q?(R.sortIndex=D,t(u,R),n(s)===null&&R===n(u)&&(S?(d(b),b=-1):S=!0,De(w,D-q))):(R.sortIndex=T,t(s,R),v||g||(v=!0,Nt(E))),R},e.unstable_shouldYield=Ee,e.unstable_wrapCallback=function(R){var L=p;return function(){var D=p;p=L;try{return R.apply(this,arguments)}finally{p=D}}}})(uc),sc.exports=uc;/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var cc=B.exports,st=sc.exports;function k(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;nt}return!1}function Qe(e,t,n,r,o,i,a){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=i,this.removeEmptyString=a}var Me={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){Me[e]=new Qe(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];Me[t]=new Qe(t,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){Me[e]=new Qe(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){Me[e]=new Qe(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){Me[e]=new Qe(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){Me[e]=new Qe(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){Me[e]=new Qe(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){Me[e]=new Qe(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){Me[e]=new Qe(e,5,!1,e.toLowerCase(),null,!1,!1)});var za=/[\-:]([a-z])/g;function ja(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(za,ja);Me[t]=new Qe(t,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(za,ja);Me[t]=new Qe(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(za,ja);Me[t]=new Qe(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){Me[e]=new Qe(e,1,!1,e.toLowerCase(),null,!1,!1)}),Me.xlinkHref=new Qe("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){Me[e]=new Qe(e,1,!1,e.toLowerCase(),null,!0,!0)});function Va(e,t,n,r){var o=Me.hasOwnProperty(t)?Me[t]:null;(o!==null?o.type!==0:r||!(2l||o[a]!==i[l]){var s=` +`+o[a].replace(" at new "," at ");return e.displayName&&s.includes("")&&(s=s.replace("",e.displayName)),s}while(1<=a&&0<=l);break}}}finally{Ja=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?Mr(e):""}function cm(e){switch(e.tag){case 5:return Mr(e.type);case 16:return Mr("Lazy");case 13:return Mr("Suspense");case 19:return Mr("SuspenseList");case 0:case 2:case 15:return e=qa(e.type,!1),e;case 11:return e=qa(e.type.render,!1),e;case 1:return e=qa(e.type,!0),e;default:return""}}function el(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Zn:return"Fragment";case Qn:return"Portal";case Wa:return"Profiler";case Ga:return"StrictMode";case Qa:return"Suspense";case Za:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case mc:return(e.displayName||"Context")+".Consumer";case hc:return(e._context.displayName||"Context")+".Provider";case Xa:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case Ya:return t=e.displayName||null,t!==null?t:el(e.type)||"Memo";case on:t=e._payload,e=e._init;try{return el(e(t))}catch{}}return null}function fm(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return el(t);case 8:return t===Ga?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function an(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function yc(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function dm(e){var t=yc(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n!="undefined"&&typeof n.get=="function"&&typeof n.set=="function"){var o=n.get,i=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(a){r=""+a,i.call(this,a)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(a){r=""+a},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function jo(e){e._valueTracker||(e._valueTracker=dm(e))}function Ec(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=yc(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function Vo(e){if(e=e||(typeof document!="undefined"?document:void 0),typeof e=="undefined")return null;try{return e.activeElement||e.body}catch{return e.body}}function tl(e,t){var n=t.checked;return de({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n!=null?n:e._wrapperState.initialChecked})}function wc(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=an(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function Sc(e,t){t=t.checked,t!=null&&Va(e,"checked",t,!1)}function nl(e,t){Sc(e,t);var n=an(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?rl(e,t.type,n):t.hasOwnProperty("defaultValue")&&rl(e,t.type,an(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function xc(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function rl(e,t,n){(t!=="number"||Vo(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var Nr=Array.isArray;function Yn(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o"+t.valueOf().toString()+"",t=Go.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Or(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Lr={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},pm=["Webkit","ms","Moz","O"];Object.keys(Lr).forEach(function(e){pm.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Lr[t]=Lr[e]})});function Ic(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||Lr.hasOwnProperty(e)&&Lr[e]?(""+t).trim():t+"px"}function Pc(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,o=Ic(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}var hm=de({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function al(e,t){if(t){if(hm[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(k(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(k(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(k(61))}if(t.style!=null&&typeof t.style!="object")throw Error(k(62))}}function ll(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var sl=null;function ul(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var cl=null,Kn=null,Jn=null;function bc(e){if(e=ro(e)){if(typeof cl!="function")throw Error(k(280));var t=e.stateNode;t&&(t=hi(t),cl(e.stateNode,e.type,t))}}function Ac(e){Kn?Jn?Jn.push(e):Jn=[e]:Kn=e}function Mc(){if(Kn){var e=Kn,t=Jn;if(Jn=Kn=null,bc(e),t)for(e=0;e>>=0,e===0?32:31-(km(e)/_m|0)|0}var Yo=64,Ko=4194304;function Br(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Jo(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,o=e.suspendedLanes,i=e.pingedLanes,a=n&268435455;if(a!==0){var l=a&~o;l!==0?r=Br(l):(i&=a,i!==0&&(r=Br(i)))}else a=n&~o,a!==0?r=Br(a):i!==0&&(r=Br(i));if(r===0)return 0;if(t!==0&&t!==r&&(t&o)===0&&(o=r&-r,i=t&-t,o>=i||o===16&&(i&4194240)!==0))return t;if((r&4)!==0&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function Ur(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-Ct(t),e[t]=n}function bm(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=Qr),lf=String.fromCharCode(32),sf=!1;function uf(e,t){switch(e){case"keyup":return o1.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function cf(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var tr=!1;function a1(e,t){switch(e){case"compositionend":return cf(t);case"keypress":return t.which!==32?null:(sf=!0,lf);case"textInput":return e=t.data,e===lf&&sf?null:e;default:return null}}function l1(e,t){if(tr)return e==="compositionend"||!Il&&uf(e,t)?(e=ef(),ri=xl=fn=null,tr=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=gf(n)}}function Ef(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Ef(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function wf(){for(var e=window,t=Vo();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=Vo(e.document)}return t}function Al(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function v1(e){var t=wf(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&Ef(n.ownerDocument.documentElement,n)){if(r!==null&&Al(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var o=n.textContent.length,i=Math.min(r.start,o);r=r.end===void 0?i:Math.min(r.end,o),!e.extend&&i>r&&(o=r,r=i,i=o),o=yf(n,i);var a=yf(n,r);o&&a&&(e.rangeCount!==1||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==a.node||e.focusOffset!==a.offset)&&(t=t.createRange(),t.setStart(o.node,o.offset),e.removeAllRanges(),i>r?(e.addRange(t),e.extend(a.node,a.offset)):(t.setEnd(a.node,a.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,nr=null,Ml=null,Jr=null,Nl=!1;function Sf(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Nl||nr==null||nr!==Vo(r)||(r=nr,"selectionStart"in r&&Al(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Jr&&Kr(Jr,r)||(Jr=r,r=fi(Ml,"onSelect"),0lr||(e.current=Gl[lr],Gl[lr]=null,lr--)}function ae(e,t){lr++,Gl[lr]=e.current,e.current=t}var hn={},$e=pn(hn),qe=pn(!1),Mn=hn;function sr(e,t){var n=e.type.contextTypes;if(!n)return hn;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o={},i;for(i in n)o[i]=t[i];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function et(e){return e=e.childContextTypes,e!=null}function mi(){ue(qe),ue($e)}function Hf(e,t,n){if($e.current!==hn)throw Error(k(168));ae($e,t),ae(qe,n)}function Df(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var o in r)if(!(o in t))throw Error(k(108,fm(e)||"Unknown",o));return de({},n,r)}function vi(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||hn,Mn=$e.current,ae($e,e),ae(qe,qe.current),!0}function Ff(e,t,n){var r=e.stateNode;if(!r)throw Error(k(169));n?(e=Df(e,t,Mn),r.__reactInternalMemoizedMergedChildContext=e,ue(qe),ue($e),ae($e,e)):ue(qe),ae(qe,n)}var Zt=null,gi=!1,Wl=!1;function Bf(e){Zt===null?Zt=[e]:Zt.push(e)}function I1(e){gi=!0,Bf(e)}function mn(){if(!Wl&&Zt!==null){Wl=!0;var e=0,t=ne;try{var n=Zt;for(ne=1;e>=a,o-=a,Kt=1<<32-Ct(t)+o|n<b?(Y=A,A=null):Y=A.sibling;var H=p(d,A,h[b],w);if(H===null){A===null&&(A=Y);break}e&&A&&H.alternate===null&&t(d,A),f=i(H,f,b),_===null?E=H:_.sibling=H,_=H,A=Y}if(b===h.length)return n(d,A),fe&&On(d,b),E;if(A===null){for(;bb?(Y=A,A=null):Y=A.sibling;var Ee=p(d,A,H.value,w);if(Ee===null){A===null&&(A=Y);break}e&&A&&Ee.alternate===null&&t(d,A),f=i(Ee,f,b),_===null?E=Ee:_.sibling=Ee,_=Ee,A=Y}if(H.done)return n(d,A),fe&&On(d,b),E;if(A===null){for(;!H.done;b++,H=h.next())H=m(d,H.value,w),H!==null&&(f=i(H,f,b),_===null?E=H:_.sibling=H,_=H);return fe&&On(d,b),E}for(A=r(d,A);!H.done;b++,H=h.next())H=g(A,d,b,H.value,w),H!==null&&(e&&H.alternate!==null&&A.delete(H.key===null?b:H.key),f=i(H,f,b),_===null?E=H:_.sibling=H,_=H);return e&&A.forEach(function(we){return t(d,we)}),fe&&On(d,b),E}function C(d,f,h,w){if(typeof h=="object"&&h!==null&&h.type===Zn&&h.key===null&&(h=h.props.children),typeof h=="object"&&h!==null){switch(h.$$typeof){case zo:e:{for(var E=h.key,_=f;_!==null;){if(_.key===E){if(E=h.type,E===Zn){if(_.tag===7){n(d,_.sibling),f=o(_,h.props.children),f.return=d,d=f;break e}}else if(_.elementType===E||typeof E=="object"&&E!==null&&E.$$typeof===on&&Kf(E)===_.type){n(d,_.sibling),f=o(_,h.props),f.ref=io(d,_,h),f.return=d,d=f;break e}n(d,_);break}else t(d,_);_=_.sibling}h.type===Zn?(f=$n(h.props.children,d.mode,w,h.key),f.return=d,d=f):(w=Wi(h.type,h.key,h.props,null,d.mode,w),w.ref=io(d,f,h),w.return=d,d=w)}return a(d);case Qn:e:{for(_=h.key;f!==null;){if(f.key===_)if(f.tag===4&&f.stateNode.containerInfo===h.containerInfo&&f.stateNode.implementation===h.implementation){n(d,f.sibling),f=o(f,h.children||[]),f.return=d,d=f;break e}else{n(d,f);break}else t(d,f);f=f.sibling}f=Us(h,d.mode,w),f.return=d,d=f}return a(d);case on:return _=h._init,C(d,f,_(h._payload),w)}if(Nr(h))return v(d,f,h,w);if(Ar(h))return S(d,f,h,w);ki(d,h)}return typeof h=="string"&&h!==""||typeof h=="number"?(h=""+h,f!==null&&f.tag===6?(n(d,f.sibling),f=o(f,h),f.return=d,d=f):(n(d,f),f=Bs(h,d.mode,w),f.return=d,d=f),a(d)):n(d,f)}return C}var hr=Jf(!0),qf=Jf(!1),ao={},Dt=pn(ao),lo=pn(ao),so=pn(ao);function Ln(e){if(e===ao)throw Error(k(174));return e}function is(e,t){switch(ae(so,t),ae(lo,e),ae(Dt,ao),e=t.nodeType,e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:il(null,"");break;default:e=e===8?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=il(t,e)}ue(Dt),ae(Dt,t)}function mr(){ue(Dt),ue(lo),ue(so)}function ed(e){Ln(so.current);var t=Ln(Dt.current),n=il(t,e.type);t!==n&&(ae(lo,e),ae(Dt,n))}function as(e){lo.current===e&&(ue(Dt),ue(lo))}var pe=pn(0);function _i(e){for(var t=e;t!==null;){if(t.tag===13){var n=t.memoizedState;if(n!==null&&(n=n.dehydrated,n===null||n.data==="$?"||n.data==="$!"))return t}else if(t.tag===19&&t.memoizedProps.revealOrder!==void 0){if((t.flags&128)!==0)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var ls=[];function ss(){for(var e=0;en?n:4,e(!0);var r=us.transition;us.transition={};try{e(!1),t()}finally{ne=n,us.transition=r}}function gd(){return gt().memoizedState}function M1(e,t,n){var r=Sn(e);n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},yd(e)?Ed(t,n):(wd(e,t,n),n=Ye(),e=Et(e,r,n),e!==null&&Sd(e,t,r))}function N1(e,t,n){var r=Sn(e),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(yd(e))Ed(t,o);else{wd(e,t,o);var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var a=t.lastRenderedState,l=i(a,n);if(o.hasEagerState=!0,o.eagerState=l,Tt(l,a))return}catch{}finally{}n=Ye(),e=Et(e,r,n),e!==null&&Sd(e,t,r)}}function yd(e){var t=e.alternate;return e===he||t!==null&&t===he}function Ed(e,t){uo=Ii=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function wd(e,t,n){tp(e)?(e=t.interleaved,e===null?(n.next=n,_t===null?_t=[t]:_t.push(t)):(n.next=e.next,e.next=n),t.interleaved=n):(e=t.pending,e===null?n.next=n:(n.next=e.next,e.next=n),t.pending=n)}function Sd(e,t,n){if((n&4194240)!==0){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,gl(e,n)}}var Ai={readContext:ht,useCallback:ze,useContext:ze,useEffect:ze,useImperativeHandle:ze,useInsertionEffect:ze,useLayoutEffect:ze,useMemo:ze,useReducer:ze,useRef:ze,useState:ze,useDebugValue:ze,useDeferredValue:ze,useTransition:ze,useMutableSource:ze,useSyncExternalStore:ze,useId:ze,unstable_isNewReconciler:!1},O1={readContext:ht,useCallback:function(e,t){return Ft().memoizedState=[e,t===void 0?null:t],e},useContext:ht,useEffect:ud,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,Pi(4194308,4,dd.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Pi(4194308,4,e,t)},useInsertionEffect:function(e,t){return Pi(4,2,e,t)},useMemo:function(e,t){var n=Ft();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Ft();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=M1.bind(null,he,e),[r.memoizedState,e]},useRef:function(e){var t=Ft();return e={current:e},t.memoizedState=e},useState:ld,useDebugValue:vs,useDeferredValue:function(e){return Ft().memoizedState=e},useTransition:function(){var e=ld(!1),t=e[0];return e=A1.bind(null,e[1]),Ft().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=he,o=Ft();if(fe){if(n===void 0)throw Error(k(407));n=n()}else{if(n=t(),Te===null)throw Error(k(349));(Hn&30)!==0||rd(r,t,n)}o.memoizedState=n;var i={value:n,getSnapshot:t};return o.queue=i,ud(id.bind(null,r,i,e),[e]),r.flags|=2048,po(9,od.bind(null,r,i,n,t),void 0,null),n},useId:function(){var e=Ft(),t=Te.identifierPrefix;if(fe){var n=Jt,r=Kt;n=(r&~(1<<32-Ct(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=co++,0<\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=a.createElement(n,{is:r.is}):(e=a.createElement(n),n==="select"&&(a=e,r.multiple?a.multiple=!0:r.size&&(a.size=r.size))):e=a.createElementNS(e,n),e[Ht]=t,e[no]=r,Rd(e,t,!1,!1),t.stateNode=e;e:{switch(a=ll(n,r),n){case"dialog":se("cancel",e),se("close",e),o=r;break;case"iframe":case"object":case"embed":se("load",e),o=r;break;case"video":case"audio":for(o=0;oyr&&(t.flags|=128,r=!0,ho(i,!1),t.lanes=4194304)}else{if(!r)if(e=_i(a),e!==null){if(t.flags|=128,r=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),ho(i,!0),i.tail===null&&i.tailMode==="hidden"&&!a.alternate&&!fe)return je(t),null}else 2*ge()-i.renderingStartTime>yr&&n!==1073741824&&(t.flags|=128,r=!0,ho(i,!1),t.lanes=4194304);i.isBackwards?(a.sibling=t.child,t.child=a):(n=i.last,n!==null?n.sibling=a:t.child=a,i.last=a)}return i.tail!==null?(t=i.tail,i.rendering=t,i.tail=t.sibling,i.renderingStartTime=ge(),t.sibling=null,n=pe.current,ae(pe,r?n&1|2:n&1),t):(je(t),null);case 22:case 23:return Hs(),r=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(t.flags|=8192),r&&(t.mode&1)!==0?(ft&1073741824)!==0&&(je(t),t.subtreeFlags&6&&(t.flags|=8192)):je(t),null;case 24:return null;case 25:return null}throw Error(k(156,t.tag))}var B1=Wt.ReactCurrentOwner,nt=!1;function Ze(e,t,n,r){t.child=e===null?qf(t,null,n,r):hr(t,e.child,n,r)}function bd(e,t,n,r,o){n=n.render;var i=t.ref;return cr(t,o),r=fs(e,t,n,r,i,o),n=ds(),e!==null&&!nt?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,qt(e,t,o)):(fe&&n&&es(t),t.flags|=1,Ze(e,t,r,o),t.child)}function Ad(e,t,n,r,o){if(e===null){var i=n.type;return typeof i=="function"&&!Fs(i)&&i.defaultProps===void 0&&n.compare===null&&n.defaultProps===void 0?(t.tag=15,t.type=i,Md(e,t,i,r,o)):(e=Wi(n.type,null,r,t,t.mode,o),e.ref=t.ref,e.return=t,t.child=e)}if(i=e.child,(e.lanes&o)===0){var a=i.memoizedProps;if(n=n.compare,n=n!==null?n:Kr,n(a,r)&&e.ref===t.ref)return qt(e,t,o)}return t.flags|=1,e=Cn(i,r),e.ref=t.ref,e.return=t,t.child=e}function Md(e,t,n,r,o){if(e!==null){var i=e.memoizedProps;if(Kr(i,r)&&e.ref===t.ref)if(nt=!1,t.pendingProps=r=i,(e.lanes&o)!==0)(e.flags&131072)!==0&&(nt=!0);else return t.lanes=e.lanes,qt(e,t,o)}return ws(e,t,n,r,o)}function Nd(e,t,n){var r=t.pendingProps,o=r.children,i=e!==null?e.memoizedState:null;if(r.mode==="hidden")if((t.mode&1)===0)t.memoizedState={baseLanes:0,cachePool:null,transitions:null},ae(gr,ft),ft|=n;else if((n&1073741824)!==0)t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=i!==null?i.baseLanes:n,ae(gr,ft),ft|=r;else return e=i!==null?i.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,ae(gr,ft),ft|=e,null;else i!==null?(r=i.baseLanes|n,t.memoizedState=null):r=n,ae(gr,ft),ft|=r;return Ze(e,t,o,n),t.child}function Od(e,t){var n=t.ref;(e===null&&n!==null||e!==null&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function ws(e,t,n,r,o){var i=et(n)?Mn:$e.current;return i=sr(t,i),cr(t,o),n=fs(e,t,n,r,i,o),r=ds(),e!==null&&!nt?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,qt(e,t,o)):(fe&&r&&es(t),t.flags|=1,Ze(e,t,n,o),t.child)}function Ld(e,t,n,r,o){if(et(n)){var i=!0;vi(t)}else i=!1;if(cr(t,o),t.stateNode===null)e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2),Gf(t,n,r),ql(t,n,r,o),r=!0;else if(e===null){var a=t.stateNode,l=t.memoizedProps;a.props=l;var s=a.context,u=n.contextType;typeof u=="object"&&u!==null?u=ht(u):(u=et(n)?Mn:$e.current,u=sr(t,u));var c=n.getDerivedStateFromProps,m=typeof c=="function"||typeof a.getSnapshotBeforeUpdate=="function";m||typeof a.UNSAFE_componentWillReceiveProps!="function"&&typeof a.componentWillReceiveProps!="function"||(l!==r||s!==u)&&Wf(t,a,r,u),vn=!1;var p=t.memoizedState;a.state=p,Si(t,r,a,o),s=t.memoizedState,l!==r||p!==s||qe.current||vn?(typeof c=="function"&&(Jl(t,n,c,r),s=t.memoizedState),(l=vn||Vf(t,n,l,r,p,s,u))?(m||typeof a.UNSAFE_componentWillMount!="function"&&typeof a.componentWillMount!="function"||(typeof a.componentWillMount=="function"&&a.componentWillMount(),typeof a.UNSAFE_componentWillMount=="function"&&a.UNSAFE_componentWillMount()),typeof a.componentDidMount=="function"&&(t.flags|=4194308)):(typeof a.componentDidMount=="function"&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=s),a.props=r,a.state=s,a.context=u,r=l):(typeof a.componentDidMount=="function"&&(t.flags|=4194308),r=!1)}else{a=t.stateNode,Uf(e,t),l=t.memoizedProps,u=t.type===t.elementType?l:kt(t.type,l),a.props=u,m=t.pendingProps,p=a.context,s=n.contextType,typeof s=="object"&&s!==null?s=ht(s):(s=et(n)?Mn:$e.current,s=sr(t,s));var g=n.getDerivedStateFromProps;(c=typeof g=="function"||typeof a.getSnapshotBeforeUpdate=="function")||typeof a.UNSAFE_componentWillReceiveProps!="function"&&typeof a.componentWillReceiveProps!="function"||(l!==m||p!==s)&&Wf(t,a,r,s),vn=!1,p=t.memoizedState,a.state=p,Si(t,r,a,o);var v=t.memoizedState;l!==m||p!==v||qe.current||vn?(typeof g=="function"&&(Jl(t,n,g,r),v=t.memoizedState),(u=vn||Vf(t,n,u,r,p,v,s)||!1)?(c||typeof a.UNSAFE_componentWillUpdate!="function"&&typeof a.componentWillUpdate!="function"||(typeof a.componentWillUpdate=="function"&&a.componentWillUpdate(r,v,s),typeof a.UNSAFE_componentWillUpdate=="function"&&a.UNSAFE_componentWillUpdate(r,v,s)),typeof a.componentDidUpdate=="function"&&(t.flags|=4),typeof a.getSnapshotBeforeUpdate=="function"&&(t.flags|=1024)):(typeof a.componentDidUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=v),a.props=r,a.state=v,a.context=s,r=u):(typeof a.componentDidUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),r=!1)}return Ss(e,t,n,r,i,o)}function Ss(e,t,n,r,o,i){Od(e,t);var a=(t.flags&128)!==0;if(!r&&!a)return o&&Ff(t,n,!1),qt(e,t,i);r=t.stateNode,B1.current=t;var l=a&&typeof n.getDerivedStateFromError!="function"?null:r.render();return t.flags|=1,e!==null&&a?(t.child=hr(t,e.child,null,i),t.child=hr(t,null,l,i)):Ze(e,t,l,i),t.memoizedState=r.state,o&&Ff(t,n,!0),t.child}function Hd(e){var t=e.stateNode;t.pendingContext?Hf(e,t.pendingContext,t.pendingContext!==t.context):t.context&&Hf(e,t.context,!1),is(e,t.containerInfo)}function Dd(e,t,n,r,o){return pr(),os(o),t.flags|=256,Ze(e,t,n,r),t.child}var Mi={dehydrated:null,treeContext:null,retryLane:0};function Ni(e){return{baseLanes:e,cachePool:null,transitions:null}}function Fd(e,t){return{baseLanes:e.baseLanes|t,cachePool:null,transitions:e.transitions}}function Bd(e,t,n){var r=t.pendingProps,o=pe.current,i=!1,a=(t.flags&128)!==0,l;if((l=a)||(l=e!==null&&e.memoizedState===null?!1:(o&2)!==0),l?(i=!0,t.flags&=-129):(e===null||e.memoizedState!==null)&&(o|=1),ae(pe,o&1),e===null)return rs(t),e=t.memoizedState,e!==null&&(e=e.dehydrated,e!==null)?((t.mode&1)===0?t.lanes=1:e.data==="$!"?t.lanes=8:t.lanes=1073741824,null):(o=r.children,e=r.fallback,i?(r=t.mode,i=t.child,o={mode:"hidden",children:o},(r&1)===0&&i!==null?(i.childLanes=0,i.pendingProps=o):i=Xi(o,r,0,null),e=$n(e,r,n,null),i.return=t,e.return=t,i.sibling=e,t.child=i,t.child.memoizedState=Ni(n),t.memoizedState=Mi,e):xs(t,o));if(o=e.memoizedState,o!==null){if(l=o.dehydrated,l!==null){if(a)return t.flags&256?(t.flags&=-257,Oi(e,t,n,Error(k(422)))):t.memoizedState!==null?(t.child=e.child,t.flags|=128,null):(i=r.fallback,o=t.mode,r=Xi({mode:"visible",children:r.children},o,0,null),i=$n(i,o,n,null),i.flags|=2,r.return=t,i.return=t,r.sibling=i,t.child=r,(t.mode&1)!==0&&hr(t,e.child,null,n),t.child.memoizedState=Ni(n),t.memoizedState=Mi,i);if((t.mode&1)===0)t=Oi(e,t,n,null);else if(l.data==="$!")t=Oi(e,t,n,Error(k(419)));else if(r=(n&e.childLanes)!==0,nt||r){if(r=Te,r!==null){switch(n&-n){case 4:i=2;break;case 16:i=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:i=32;break;case 536870912:i=268435456;break;default:i=0}r=(i&(r.suspendedLanes|n))!==0?0:i,r!==0&&r!==o.retryLane&&(o.retryLane=r,Et(e,r,-1))}Ds(),t=Oi(e,t,n,Error(k(421)))}else l.data==="$?"?(t.flags|=128,t.child=e.child,t=K1.bind(null,e),l._reactRetry=t,t=null):(n=o.treeContext,tt=Xt(l.nextSibling),ct=t,fe=!0,Rt=null,n!==null&&(mt[vt++]=Kt,mt[vt++]=Jt,mt[vt++]=Nn,Kt=n.id,Jt=n.overflow,Nn=t),t=xs(t,t.pendingProps.children),t.flags|=4096);return t}return i?(r=$d(e,t,r.children,r.fallback,n),i=t.child,o=e.child.memoizedState,i.memoizedState=o===null?Ni(n):Fd(o,n),i.childLanes=e.childLanes&~n,t.memoizedState=Mi,r):(n=Ud(e,t,r.children,n),t.memoizedState=null,n)}return i?(r=$d(e,t,r.children,r.fallback,n),i=t.child,o=e.child.memoizedState,i.memoizedState=o===null?Ni(n):Fd(o,n),i.childLanes=e.childLanes&~n,t.memoizedState=Mi,r):(n=Ud(e,t,r.children,n),t.memoizedState=null,n)}function xs(e,t){return t=Xi({mode:"visible",children:t},e.mode,0,null),t.return=e,e.child=t}function Ud(e,t,n,r){var o=e.child;return e=o.sibling,n=Cn(o,{mode:"visible",children:n}),(t.mode&1)===0&&(n.lanes=r),n.return=t,n.sibling=null,e!==null&&(r=t.deletions,r===null?(t.deletions=[e],t.flags|=16):r.push(e)),t.child=n}function $d(e,t,n,r,o){var i=t.mode;e=e.child;var a=e.sibling,l={mode:"hidden",children:n};return(i&1)===0&&t.child!==e?(n=t.child,n.childLanes=0,n.pendingProps=l,t.deletions=null):(n=Cn(e,l),n.subtreeFlags=e.subtreeFlags&14680064),a!==null?r=Cn(a,r):(r=$n(r,i,o,null),r.flags|=2),r.return=t,n.return=t,n.sibling=r,t.child=n,r}function Oi(e,t,n,r){return r!==null&&os(r),hr(t,e.child,null,n),e=xs(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function zd(e,t,n){e.lanes|=t;var r=e.alternate;r!==null&&(r.lanes|=t),Yl(e.return,t,n)}function Cs(e,t,n,r,o){var i=e.memoizedState;i===null?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:o}:(i.isBackwards=t,i.rendering=null,i.renderingStartTime=0,i.last=r,i.tail=n,i.tailMode=o)}function jd(e,t,n){var r=t.pendingProps,o=r.revealOrder,i=r.tail;if(Ze(e,t,r.children,n),r=pe.current,(r&2)!==0)r=r&1|2,t.flags|=128;else{if(e!==null&&(e.flags&128)!==0)e:for(e=t.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&zd(e,n,t);else if(e.tag===19)zd(e,n,t);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;e.sibling===null;){if(e.return===null||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(ae(pe,r),(t.mode&1)===0)t.memoizedState=null;else switch(o){case"forwards":for(n=t.child,o=null;n!==null;)e=n.alternate,e!==null&&_i(e)===null&&(o=n),n=n.sibling;n=o,n===null?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),Cs(t,!1,o,n,i);break;case"backwards":for(n=null,o=t.child,t.child=null;o!==null;){if(e=o.alternate,e!==null&&_i(e)===null){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}Cs(t,!0,n,null,i);break;case"together":Cs(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function qt(e,t,n){if(e!==null&&(t.dependencies=e.dependencies),Dn|=t.lanes,(n&t.childLanes)===0)return null;if(e!==null&&t.child!==e.child)throw Error(k(153));if(t.child!==null){for(e=t.child,n=Cn(e,e.pendingProps),t.child=n,n.return=t;e.sibling!==null;)e=e.sibling,n=n.sibling=Cn(e,e.pendingProps),n.return=t;n.sibling=null}return t.child}function U1(e,t,n){switch(t.tag){case 3:Hd(t),pr();break;case 5:ed(t);break;case 1:et(t.type)&&vi(t);break;case 4:is(t,t.stateNode.containerInfo);break;case 10:var r=t.type._context,o=t.memoizedProps.value;ae(yi,r._currentValue),r._currentValue=o;break;case 13:if(r=t.memoizedState,r!==null)return r.dehydrated!==null?(ae(pe,pe.current&1),t.flags|=128,null):(n&t.child.childLanes)!==0?Bd(e,t,n):(ae(pe,pe.current&1),e=qt(e,t,n),e!==null?e.sibling:null);ae(pe,pe.current&1);break;case 19:if(r=(n&t.childLanes)!==0,(e.flags&128)!==0){if(r)return jd(e,t,n);t.flags|=128}if(o=t.memoizedState,o!==null&&(o.rendering=null,o.tail=null,o.lastEffect=null),ae(pe,pe.current),r)break;return null;case 22:case 23:return t.lanes=0,Nd(e,t,n)}return qt(e,t,n)}function $1(e,t){switch(ts(t),t.tag){case 1:return et(t.type)&&mi(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return mr(),ue(qe),ue($e),ss(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return as(t),null;case 13:if(ue(pe),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(k(340));pr()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return ue(pe),null;case 4:return mr(),null;case 10:return Zl(t.type._context),null;case 22:case 23:return Hs(),null;case 24:return null;default:return null}}var Li=!1,Ve=!1,z1=typeof WeakSet=="function"?WeakSet:Set,N=null;function vr(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){me(e,t,r)}else n.current=null}function Ts(e,t,n){try{n()}catch(r){me(e,t,r)}}var Vd=!1;function j1(e,t){if(Bl=ti,e=wf(),Al(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var o=r.anchorOffset,i=r.focusNode;r=r.focusOffset;try{n.nodeType,i.nodeType}catch{n=null;break e}var a=0,l=-1,s=-1,u=0,c=0,m=e,p=null;t:for(;;){for(var g;m!==n||o!==0&&m.nodeType!==3||(l=a+o),m!==i||r!==0&&m.nodeType!==3||(s=a+r),m.nodeType===3&&(a+=m.nodeValue.length),(g=m.firstChild)!==null;)p=m,m=g;for(;;){if(m===e)break t;if(p===n&&++u===o&&(l=a),p===i&&++c===r&&(s=a),(g=m.nextSibling)!==null)break;m=p,p=m.parentNode}m=g}n=l===-1||s===-1?null:{start:l,end:s}}else n=null}n=n||{start:0,end:0}}else n=null;for(Ul={focusedElem:e,selectionRange:n},ti=!1,N=t;N!==null;)if(t=N,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,N=e;else for(;N!==null;){t=N;try{var v=t.alternate;if((t.flags&1024)!==0)switch(t.tag){case 0:case 11:case 15:break;case 1:if(v!==null){var S=v.memoizedProps,C=v.memoizedState,d=t.stateNode,f=d.getSnapshotBeforeUpdate(t.elementType===t.type?S:kt(t.type,S),C);d.__reactInternalSnapshotBeforeUpdate=f}break;case 3:var h=t.stateNode.containerInfo;if(h.nodeType===1)h.textContent="";else if(h.nodeType===9){var w=h.body;w!=null&&(w.textContent="")}break;case 5:case 6:case 4:case 17:break;default:throw Error(k(163))}}catch(E){me(t,t.return,E)}if(e=t.sibling,e!==null){e.return=t.return,N=e;break}N=t.return}return v=Vd,Vd=!1,v}function mo(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var o=r=r.next;do{if((o.tag&e)===e){var i=o.destroy;o.destroy=void 0,i!==void 0&&Ts(t,n,i)}o=o.next}while(o!==r)}}function Hi(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function ks(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t=="function"?t(e):t.current=e}}function Gd(e){var t=e.alternate;t!==null&&(e.alternate=null,Gd(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Ht],delete t[no],delete t[Vl],delete t[_1],delete t[R1])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Wd(e){return e.tag===5||e.tag===3||e.tag===4}function Xd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Wd(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function _s(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=pi));else if(r!==4&&(e=e.child,e!==null))for(_s(e,t,n),e=e.sibling;e!==null;)_s(e,t,n),e=e.sibling}function Rs(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(Rs(e,t,n),e=e.sibling;e!==null;)Rs(e,t,n),e=e.sibling}var Ne=null,It=!1;function yn(e,t,n){for(n=n.child;n!==null;)Qd(e,t,n),n=n.sibling}function Qd(e,t,n){if(Lt&&typeof Lt.onCommitFiberUnmount=="function")try{Lt.onCommitFiberUnmount(Zo,n)}catch{}switch(n.tag){case 5:Ve||vr(n,t);case 6:var r=Ne,o=It;Ne=null,yn(e,t,n),Ne=r,It=o,Ne!==null&&(It?(e=Ne,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):Ne.removeChild(n.stateNode));break;case 18:Ne!==null&&(It?(e=Ne,n=n.stateNode,e.nodeType===8?jl(e.parentNode,n):e.nodeType===1&&jl(e,n),Gr(e)):jl(Ne,n.stateNode));break;case 4:r=Ne,o=It,Ne=n.stateNode.containerInfo,It=!0,yn(e,t,n),Ne=r,It=o;break;case 0:case 11:case 14:case 15:if(!Ve&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){o=r=r.next;do{var i=o,a=i.destroy;i=i.tag,a!==void 0&&((i&2)!==0||(i&4)!==0)&&Ts(n,t,a),o=o.next}while(o!==r)}yn(e,t,n);break;case 1:if(!Ve&&(vr(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(l){me(n,t,l)}yn(e,t,n);break;case 21:yn(e,t,n);break;case 22:n.mode&1?(Ve=(r=Ve)||n.memoizedState!==null,yn(e,t,n),Ve=r):yn(e,t,n);break;default:yn(e,t,n)}}function Zd(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new z1),t.forEach(function(r){var o=J1.bind(null,e,r);n.has(r)||(n.add(r),r.then(o,o))})}}function Pt(e,t){var n=t.deletions;if(n!==null)for(var r=0;ro&&(o=a),r&=~i}if(r=o,r=ge()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*G1(r/1960))-r,10e?16:e,wn===null)var r=!1;else{if(e=wn,wn=null,$i=0,(K&6)!==0)throw Error(k(331));var o=K;for(K|=4,N=e.current;N!==null;){var i=N,a=i.child;if((N.flags&16)!==0){var l=i.deletions;if(l!==null){for(var s=0;sge()-bs?Bn(e,0):Ps|=n),ot(e,t)}function up(e,t){t===0&&((e.mode&1)===0?t=1:(t=Ko,Ko<<=1,(Ko&130023424)===0&&(Ko=4194304)));var n=Ye();e=Vi(e,t),e!==null&&(Ur(e,t,n),ot(e,n))}function K1(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),up(e,n)}function J1(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;o!==null&&(n=o.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(k(314))}r!==null&&r.delete(t),up(e,n)}var cp;cp=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||qe.current)nt=!0;else{if((e.lanes&n)===0&&(t.flags&128)===0)return nt=!1,U1(e,t,n);nt=(e.flags&131072)!==0}else nt=!1,fe&&(t.flags&1048576)!==0&&Xf(t,Ti,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps;var o=sr(t,$e.current);cr(t,n),o=fs(null,t,r,e,o,n);var i=ds();return t.flags|=1,typeof o=="object"&&o!==null&&typeof o.render=="function"&&o.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,et(r)?(i=!0,vi(t)):i=!1,t.memoizedState=o.state!==null&&o.state!==void 0?o.state:null,Kl(t),o.updater=xi,t.stateNode=o,o._reactInternals=t,ql(t,r,e,n),t=Ss(null,t,r,!0,i,n)):(t.tag=0,fe&&i&&es(t),Ze(null,t,o,n),t=t.child),t;case 16:r=t.elementType;e:{switch(e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,o=r._init,r=o(r._payload),t.type=r,o=t.tag=ev(r),e=kt(r,e),o){case 0:t=ws(null,t,r,e,n);break e;case 1:t=Ld(null,t,r,e,n);break e;case 11:t=bd(null,t,r,e,n);break e;case 14:t=Ad(null,t,r,kt(r.type,e),n);break e}throw Error(k(306,r,""))}return t;case 0:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:kt(r,o),ws(e,t,r,o,n);case 1:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:kt(r,o),Ld(e,t,r,o,n);case 3:e:{if(Hd(t),e===null)throw Error(k(387));r=t.pendingProps,i=t.memoizedState,o=i.element,Uf(e,t),Si(t,r,null,n);var a=t.memoizedState;if(r=a.element,i.isDehydrated)if(i={element:r,isDehydrated:!1,cache:a.cache,pendingSuspenseBoundaries:a.pendingSuspenseBoundaries,transitions:a.transitions},t.updateQueue.baseState=i,t.memoizedState=i,t.flags&256){o=Error(k(423)),t=Dd(e,t,r,n,o);break e}else if(r!==o){o=Error(k(424)),t=Dd(e,t,r,n,o);break e}else for(tt=Xt(t.stateNode.containerInfo.firstChild),ct=t,fe=!0,Rt=null,n=qf(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(pr(),r===o){t=qt(e,t,n);break e}Ze(e,t,r,n)}t=t.child}return t;case 5:return ed(t),e===null&&rs(t),r=t.type,o=t.pendingProps,i=e!==null?e.memoizedProps:null,a=o.children,$l(r,o)?a=null:i!==null&&$l(r,i)&&(t.flags|=32),Od(e,t),Ze(e,t,a,n),t.child;case 6:return e===null&&rs(t),null;case 13:return Bd(e,t,n);case 4:return is(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=hr(t,null,r,n):Ze(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:kt(r,o),bd(e,t,r,o,n);case 7:return Ze(e,t,t.pendingProps,n),t.child;case 8:return Ze(e,t,t.pendingProps.children,n),t.child;case 12:return Ze(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,o=t.pendingProps,i=t.memoizedProps,a=o.value,ae(yi,r._currentValue),r._currentValue=a,i!==null)if(Tt(i.value,a)){if(i.children===o.children&&!qe.current){t=qt(e,t,n);break e}}else for(i=t.child,i!==null&&(i.return=t);i!==null;){var l=i.dependencies;if(l!==null){a=i.child;for(var s=l.firstContext;s!==null;){if(s.context===r){if(i.tag===1){s=Yt(-1,n&-n),s.tag=2;var u=i.updateQueue;if(u!==null){u=u.shared;var c=u.pending;c===null?s.next=s:(s.next=c.next,c.next=s),u.pending=s}}i.lanes|=n,s=i.alternate,s!==null&&(s.lanes|=n),Yl(i.return,n,t),l.lanes|=n;break}s=s.next}}else if(i.tag===10)a=i.type===t.type?null:i.child;else if(i.tag===18){if(a=i.return,a===null)throw Error(k(341));a.lanes|=n,l=a.alternate,l!==null&&(l.lanes|=n),Yl(a,n,t),a=i.sibling}else a=i.child;if(a!==null)a.return=i;else for(a=i;a!==null;){if(a===t){a=null;break}if(i=a.sibling,i!==null){i.return=a.return,a=i;break}a=a.return}i=a}Ze(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=t.pendingProps.children,cr(t,n),o=ht(o),r=r(o),t.flags|=1,Ze(e,t,r,n),t.child;case 14:return r=t.type,o=kt(r,t.pendingProps),o=kt(r.type,o),Ad(e,t,r,o,n);case 15:return Md(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:kt(r,o),e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2),t.tag=1,et(r)?(e=!0,vi(t)):e=!1,cr(t,n),Gf(t,r,o),ql(t,r,o,n),Ss(null,t,r,!0,e,n);case 19:return jd(e,t,n);case 22:return Nd(e,t,n)}throw Error(k(156,t.tag))};function fp(e,t){return Uc(e,t)}function q1(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function wt(e,t,n,r){return new q1(e,t,n,r)}function Fs(e){return e=e.prototype,!(!e||!e.isReactComponent)}function ev(e){if(typeof e=="function")return Fs(e)?1:0;if(e!=null){if(e=e.$$typeof,e===Xa)return 11;if(e===Ya)return 14}return 2}function Cn(e,t){var n=e.alternate;return n===null?(n=wt(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Wi(e,t,n,r,o,i){var a=2;if(r=e,typeof e=="function")Fs(e)&&(a=1);else if(typeof e=="string")a=5;else e:switch(e){case Zn:return $n(n.children,o,i,t);case Ga:a=8,o|=8;break;case Wa:return e=wt(12,n,t,o|2),e.elementType=Wa,e.lanes=i,e;case Qa:return e=wt(13,n,t,o),e.elementType=Qa,e.lanes=i,e;case Za:return e=wt(19,n,t,o),e.elementType=Za,e.lanes=i,e;case vc:return Xi(n,o,i,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case hc:a=10;break e;case mc:a=9;break e;case Xa:a=11;break e;case Ya:a=14;break e;case on:a=16,r=null;break e}throw Error(k(130,e==null?e:typeof e,""))}return t=wt(a,n,t,o),t.elementType=e,t.type=r,t.lanes=i,t}function $n(e,t,n,r){return e=wt(7,e,r,t),e.lanes=n,e}function Xi(e,t,n,r){return e=wt(22,e,r,t),e.elementType=vc,e.lanes=n,e.stateNode={},e}function Bs(e,t,n){return e=wt(6,e,null,t),e.lanes=n,e}function Us(e,t,n){return t=wt(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function tv(e,t,n,r,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=vl(0),this.expirationTimes=vl(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=vl(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function $s(e,t,n,r,o,i,a,l,s){return e=new tv(e,t,n,l,s),t===1?(t=1,i===!0&&(t|=8)):t=0,i=wt(3,null,null,t),e.current=i,i.stateNode=e,i.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Kl(i),e}function nv(e,t,n){var r=3oe)&&(Ue=(U=U.replace(" ",":")).length),0F&&(F=(I=I.trim()).charCodeAt(0)),F){case 38:return I.replace(d,"$1"+T.trim());case 58:return T.trim()+I.replace(d,"$1"+T.trim());default:if(0<1*M&&0P.charCodeAt(8))break;case 115:y=y.replace(P,"-webkit-"+P)+";"+y;break;case 207:case 102:y=y.replace(P,"-webkit-"+(102M.charCodeAt(0)&&(M=M.trim()),q=M,M=[q],01?t-1:0),r=1;r0?" Args: "+n.join(", "):""))}var Dv=function(){function e(n){this.groupSizes=new Uint32Array(512),this.length=512,this.tag=n}var t=e.prototype;return t.indexOfGroup=function(n){for(var r=0,o=0;o=this.groupSizes.length){for(var o=this.groupSizes,i=o.length,a=i;n>=a;)(a<<=1)<0&&bo(16,""+n);this.groupSizes=new Uint32Array(a),this.groupSizes.set(o),this.length=a;for(var l=i;l=this.length||this.groupSizes[n]===0)return r;for(var o=this.groupSizes[n],i=this.indexOfGroup(n),a=i+o,l=i;l=Ao&&(Ao=t+1),pa.set(e,t),ha.set(t,e)},Uv="style["+wr+'][data-styled-version="5.3.5"]',$v=new RegExp("^"+wr+'\\.g(\\d+)\\[id="([\\w\\d-]+)"\\].*?"([^"]*)'),zv=function(e,t,n){for(var r,o=n.split(","),i=0,a=o.length;i=0;u--){var c=s[u];if(c&&c.nodeType===1&&c.hasAttribute(wr))return c}}(n),i=o!==void 0?o.nextSibling:null;r.setAttribute(wr,"active"),r.setAttribute("data-styled-version","5.3.5");var a=Vv();return a&&r.setAttribute("nonce",a),n.insertBefore(r,i),r},Gv=function(){function e(n){var r=this.element=Op(n);r.appendChild(document.createTextNode("")),this.sheet=function(o){if(o.sheet)return o.sheet;for(var i=document.styleSheets,a=0,l=i.length;a=0){var o=document.createTextNode(r),i=this.nodes[n];return this.element.insertBefore(o,i||null),this.length++,!0}return!1},t.deleteRule=function(n){this.element.removeChild(this.nodes[n]),this.length--},t.getRule=function(n){return n0&&(m+=p+",")}),i+=""+u+c+'{content:"'+m+`"}/*!sc*/ +`}}}return i}(this)},e}(),Zv=/(a)(d)/gi,Hp=function(e){return String.fromCharCode(e+(e>25?39:97))};function tu(e){var t,n="";for(t=Math.abs(e);t>52;t=t/52|0)n=Hp(t%52)+n;return(Hp(t%52)+n).replace(Zv,"$1-$2")}var Sr=function(e,t){for(var n=t.length;n;)e=33*e^t.charCodeAt(--n);return e},Dp=function(e){return Sr(5381,e)};function Fp(e){for(var t=0;t>>0);if(!n.hasNameForId(o,l)){var s=r(a,"."+l,void 0,o);n.insertRules(o,l,s)}i.push(l),this.staticRulesId=l}else{for(var u=this.rules.length,c=Sr(this.baseHash,r.hash),m="",p=0;p>>0);if(!n.hasNameForId(o,C)){var d=r(m,"."+C,void 0,o);n.insertRules(o,C,d)}i.push(C)}}return i.join(" ")},e}(),Jv=/^\s*\/\/.*$/gm,qv=[":","[",".","#"];function Bp(e){var t,n,r,o,i=e===void 0?Tn:e,a=i.options,l=a===void 0?Tn:a,s=i.plugins,u=s===void 0?da:s,c=new yv(l),m=[],p=function(S){function C(d){if(d)try{S(d+"}")}catch{}}return function(d,f,h,w,E,_,A,b,Y,H){switch(d){case 1:if(Y===0&&f.charCodeAt(0)===64)return S(f+";"),"";break;case 2:if(b===0)return f+"/*|*/";break;case 3:switch(b){case 102:case 112:return S(h[0]+f),"";default:return f+(H===0?"/*|*/":"")}case-2:f.split("/*|*/}").forEach(C)}}}(function(S){m.push(S)}),g=function(S,C,d){return C===0&&qv.indexOf(d[n.length])!==-1||d.match(o)?S:"."+t};function v(S,C,d,f){f===void 0&&(f="&");var h=S.replace(Jv,""),w=C&&d?d+" "+C+" { "+h+" }":h;return t=f,n=C,r=new RegExp("\\"+n+"\\b","g"),o=new RegExp("(\\"+n+"\\b){2,}"),c(d||!C?"":C,w)}return c.use([].concat(u,[function(S,C,d){S===2&&d.length&&d[0].lastIndexOf(n)>0&&(d[0]=d[0].replace(r,g))},p,function(S){if(S===-2){var C=m;return m=[],C}}])),v.hash=u.length?u.reduce(function(S,C){return C.name||bo(15),Sr(S,C.name)},5381).toString():"",v}var nu=rn.createContext();nu.Consumer;var ru=rn.createContext(),eg=(ru.Consumer,new va),ou=Bp();function iu(){return B.exports.useContext(nu)||eg}function Up(){return B.exports.useContext(ru)||ou}function tg(e){var t=B.exports.useState(e.stylisPlugins),n=t[0],r=t[1],o=iu(),i=B.exports.useMemo(function(){var l=o;return e.sheet?l=e.sheet:e.target&&(l=l.reconstructWithOptions({target:e.target},!1)),e.disableCSSOMInjection&&(l=l.reconstructWithOptions({useCSSOMInjection:!1})),l},[e.disableCSSOMInjection,e.sheet,e.target]),a=B.exports.useMemo(function(){return Bp({options:{prefix:!e.disableVendorPrefixes},plugins:n})},[e.disableVendorPrefixes,n]);return B.exports.useEffect(function(){gv(n,e.stylisPlugins)||r(e.stylisPlugins)},[e.stylisPlugins]),rn.createElement(nu.Provider,{value:i},rn.createElement(ru.Provider,{value:a},e.children))}var ng=function(){function e(t,n){var r=this;this.inject=function(o,i){i===void 0&&(i=ou);var a=r.name+i.hash;o.hasNameForId(r.id,a)||o.insertRules(r.id,a,i(r.rules,a,"@keyframes"))},this.toString=function(){return bo(12,String(r.name))},this.name=t,this.id="sc-keyframes-"+t,this.rules=n}return e.prototype.getName=function(t){return t===void 0&&(t=ou),this.name+t.hash},e}(),rg=/([A-Z])/,og=/([A-Z])/g,ig=/^ms-/,ag=function(e){return"-"+e.toLowerCase()};function $p(e){return rg.test(e)?e.replace(og,ag).replace(ig,"-ms-"):e}var zp=function(e){return e==null||e===!1||e===""};function zn(e,t,n,r){if(Array.isArray(e)){for(var o,i=[],a=0,l=e.length;a1?t-1:0),r=1;r?@[\\\]^`{|}~-]+/g,sg=/(^-|-$)/g;function au(e){return e.replace(lg,"-").replace(sg,"")}var Wp=function(e){return tu(Dp(e)>>>0)};function ga(e){return typeof e=="string"&&!0}var lu=function(e){return typeof e=="function"||typeof e=="object"&&e!==null&&!Array.isArray(e)},ug=function(e){return e!=="__proto__"&&e!=="constructor"&&e!=="prototype"};function cg(e,t,n){var r=e[n];lu(t)&&lu(r)?Xp(r,t):e[n]=t}function Xp(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r=0||(H[b]=_[b]);return H}(t,["componentId"]),E=h&&h+"-"+(ga(f)?f:au(Np(f)));return Qp(f,Ut({},w,{attrs:p,componentId:E}),n)},Object.defineProperty(v,"defaultProps",{get:function(){return this._foldedDefaultProps},set:function(f){this._foldedDefaultProps=r?Xp({},e.defaultProps,f):f}}),v.toString=function(){return"."+v.styledComponentId},o&&Ov(v,e,{attrs:!0,componentStyle:!0,displayName:!0,foldedComponentIds:!0,shouldForwardProp:!0,styledComponentId:!0,target:!0,withComponent:!0}),v}var cu=function(e){return function t(n,r,o){if(o===void 0&&(o=Tn),!Gs.exports.isValidElementType(r))return bo(1,String(r));var i=function(){return n(r,o,Vp.apply(void 0,arguments))};return i.withConfig=function(a){return t(n,r,Ut({},o,{},a))},i.attrs=function(a){return t(n,r,Ut({},o,{attrs:Array.prototype.concat(o.attrs,a).filter(Boolean)}))},i}(Qp,e)};["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","marquee","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","marker","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","textPath","tspan"].forEach(function(e){cu[e]=cu(e)});var fg=function(){function e(n,r){this.rules=n,this.componentId=r,this.isStatic=Fp(n),va.registerId(this.componentId+1)}var t=e.prototype;return t.createStyles=function(n,r,o,i){var a=i(zn(this.rules,r,o,i).join(""),""),l=this.componentId+n;o.insertRules(l,l,a)},t.removeStyles=function(n,r){r.clearRules(this.componentId+n)},t.renderStyles=function(n,r,o,i){n>2&&va.registerId(this.componentId+n),this.removeStyles(n,o),this.createStyles(n,r,o,i)},e}();function dg(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{},activeSecondaryMenuItemId:"",setActiveSecondaryMenuItemId:e=>{},secondaryMenuOpen:!1,setSecondaryMenuOpen:e=>{},activeTertiaryMenuItemId:"",setActiveTertiaryMenuItemId:e=>{},tertiaryMenuOpen:!1,setTertiaryMenuOpen:e=>{}}),wg="main-menu",Kp="menu",Sg="back";function xg(e){const{width:t=10,height:n=14,fill:r=G.textTertiary}=e;return x("svg",{xmlns:"http://www.w3.org/2000/svg",width:t,height:n,viewBox:"0 0 512 512",fill:r,strokeWidth:"1.5",children:x("path",{d:"M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160zm352-160l-160 160c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L301.3 256 438.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0z"})})}const Cg=_e.div` + background: ${G.backgroundPrimary}; + border-right: 1px solid ${G.neutralGrey}; + bottom: 0; + display: block; + left: 215px; + overflow-x: hidden; + overflow-y: auto; + position: fixed; + top: 50px; + opacity: 0; + visibility: hidden; + ${({isVisible:e})=>e?"opacity: 1; visibility: visible;":""} + width: 235px; + padding-top: 20px; + z-index: 1030; +`,Tg=_e.div` + display: flex; + align-items: center; + color: ${G.text}; + font-weight: 600; + justify-content: flex-end; + padding-inline: 24px; +`,kg=_e.ul` + margin-top: 10px; + padding-left: 10px; + padding-right: 0px; +`,_g=_e.div` + display: flex; + align-items: center; + cursor: pointer; + + &:hover > svg { + fill: ${G.blue}; + } +`;function Rg(e){const{isOpen:t,children:n}=e,{setSecondaryMenuOpen:r,setTertiaryMenuOpen:o,setActiveSecondaryMenuItemId:i,setActiveTertiaryMenuItemId:a}=B.exports.useContext(Mo);return ye(Cg,{isVisible:t,"data-id":Kp,children:[x(Tg,{children:x(_g,{onClick:s=>{s.stopPropagation(),r(!1),o(!1),i(""),a("")},"data-back":Sg,children:x(xg,{})})}),x(kg,{children:n})]})}const Ig=_e.li` + position: relative; + display: block; + margin-bottom: -1px; + padding-left: 4px; + color: ${({isActive:e})=>e?G.blue:""}; + ${({fixBottom:e})=>e&&` + @media (min-height: 636px) { + position: fixed; + bottom: 64px; + }`} + + &:first-child { + border-top: 0px; + } +`,Pg=_e.a` + width: 200px; + color: ${({isActive:e})=>e?G.blue:G.textTertiary}; + cursor: pointer; + opacity: ${({isDisabled:e})=>e?"0.5":"1"}; + pointer-events: ${({isDisabled:e})=>e?"none":"auto"}; + font-size: 14px; + font-weight: ${({isActive:e})=>e?"600":"400"}; + height: 40px; + line-height: 26px; + position: relative; + white-space: nowrap; + text-decoration: none; + display: flex; + column-gap: 10px; + padding-right: 5px; + ${({isActive:e})=>e&&` + &:before { + background: #e5eeff; + content: " "; + border-radius: 8px; + width: 28px; + height: 28px; + z-index: 0; + left: -4px; + position: absolute; + top: 6px; + }`} + + &:hover { + font-weight: 600; + + span > svg > path { + stroke: ${G.blue}; + } + + span > svg { + stroke-width: 3px; + } + + span > svg > g > path { + stroke: ${G.blue}; + } + } +`,Jp=_e.span` + display: inline-flex; + align-items: center; + color: ${G.inactive}; + float: left; + font-size: 16px; + line-height: 26px; + text-align: center; + width: 24px; + z-index: 1; +`,bg=_e.span` + display: flex; + line-height: 25px; + flex: 1; + max-width: none; + padding-right: 15px; + overflow: hidden; + text-overflow: ellipsis; + align-items: center; +`;function kn(e){const{label:t,renderIcon:n,fixBottom:r,children:o,id:i,onClick:a,href:l,dataId:s,className:u="",errorTooltipLabel:c="",hasError:m}=e,{activeListGroupItemId:p,setActiveListGroupItemId:g,setSecondaryMenuOpen:v,secondaryMenuOpen:S,setActiveTertiaryMenuItemId:C,setActiveSecondaryMenuItemId:d,setTertiaryMenuOpen:f}=B.exports.useContext(Mo),h=p===i,w=!!o,E=m;return ye(Ig,B0(xt({isActive:h,fixBottom:r,onClick:()=>{E||(g(i),w?(v(!0),C(""),d("")):(v(!1),f(!1),d(""),C(""),a&&a()))},className:`${u}`,"data-id":s},m&&{"aria-label":c,"data-balloon-pos":"down","data-balloon-length":"medium"}),{children:[ye(Pg,{isActive:h,href:l,isDisabled:E,children:[x(Jp,{children:n({stroke:h?G.blue:G.inactive})}),x(bg,{children:t}),w&&x(Jp,{children:x(Yp,{fill:h?G.blue:G.inactive})})]}),w&&h&&S&&x(Rg,{isOpen:!0,title:t,children:o})]}))}function Ag(e){const{width:t=20,height:n=20,fill:r="none",stroke:o=G.inactive,strokeWidth:i=1.5}=e;return ye("svg",{width:t,height:n,viewBox:`0 0 ${t} ${n}`,fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M8.33325 5.41663V4.58329C8.33325 3.66282 9.07944 2.91663 9.99992 2.91663H15.4166C16.3371 2.91663 17.0833 3.66282 17.0833 4.58329V9.99996C17.0833 10.9204 16.3371 11.6666 15.4166 11.6666H14.5833M4.99992 16.6666H10.8333C11.7537 16.6666 12.4999 15.9204 12.4999 15V9.16663C12.4999 8.24615 11.7537 7.49996 10.8333 7.49996H4.99992C4.07944 7.49996 3.33325 8.24615 3.33325 9.16663V15C3.33325 15.9204 4.07944 16.6666 4.99992 16.6666Z",stroke:o,strokeWidth:i}),x("mask",{id:"mask0_277_1596",maskUnits:"userSpaceOnUse",x:"1",y:"0",width:"18",height:"20",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M8.33325 5.41663V4.58329C8.33325 3.66282 9.07944 2.91663 9.99992 2.91663H15.4166C16.3371 2.91663 17.0833 3.66282 17.0833 4.58329V9.99996C17.0833 10.9204 16.3371 11.6666 15.4166 11.6666H14.5833M4.99992 16.6666H10.8333C11.7537 16.6666 12.4999 15.9204 12.4999 15V9.16663C12.4999 8.24615 11.7537 7.49996 10.8333 7.49996H4.99992C4.07944 7.49996 3.33325 8.24615 3.33325 9.16663V15C3.33325 15.9204 4.07944 16.6666 4.99992 16.6666Z",fill:"white"})}),x("g",{mask:"url(#mask0_277_1596)",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M0 0H20V20H0V0Z",fill:r})})]})}function Mg(e){const{width:t=20,height:n=20,fill:r="none",stroke:o=G.inactive,strokeWidth:i=1.5}=e;return ye("svg",{width:t,height:n,viewBox:`0 0 ${t} ${n}`,fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.0002 9.99998C10.0002 9.53974 10.3733 9.16665 10.8335 9.16665H15.8335C16.2937 9.16665 16.6668 9.53974 16.6668 9.99998V15.8333C16.6668 16.2936 16.2937 16.6666 15.8335 16.6666H10.8335C10.3733 16.6666 10.0002 16.2936 10.0002 15.8333V9.99998Z",stroke:o,strokeWidth:i}),x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M3.3335 4.16665C3.3335 3.70641 3.70659 3.33331 4.16683 3.33331H6.66683C7.12707 3.33331 7.50016 3.70641 7.50016 4.16665V15.8333C7.50016 16.2936 7.12707 16.6666 6.66683 16.6666H4.16683C3.70659 16.6666 3.3335 16.2936 3.3335 15.8333V4.16665Z",stroke:o,strokeWidth:i}),x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.0002 4.16665C10.0002 3.70641 10.3733 3.33331 10.8335 3.33331H15.8335C16.2937 3.33331 16.6668 3.70641 16.6668 4.16665V5.83331C16.6668 6.29355 16.2937 6.66665 15.8335 6.66665H10.8335C10.3733 6.66665 10.0002 6.29355 10.0002 5.83331V4.16665Z",stroke:o,strokeWidth:i}),ye("mask",{id:"mask0_277_1709",maskUnits:"userSpaceOnUse",x:"0",y:"1",width:"20",height:"18",children:[x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.0002 9.99998C10.0002 9.53974 10.3733 9.16665 10.8335 9.16665H15.8335C16.2937 9.16665 16.6668 9.53974 16.6668 9.99998V15.8333C16.6668 16.2936 16.2937 16.6666 15.8335 16.6666H10.8335C10.3733 16.6666 10.0002 16.2936 10.0002 15.8333V9.99998Z",fill:"white"}),x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.0002 9.99998C10.0002 9.53974 10.3733 9.16665 10.8335 9.16665H15.8335C16.2937 9.16665 16.6668 9.53974 16.6668 9.99998V15.8333C16.6668 16.2936 16.2937 16.6666 15.8335 16.6666H10.8335C10.3733 16.6666 10.0002 16.2936 10.0002 15.8333V9.99998Z",stroke:o,strokeWidth:i}),x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.0002 4.16665C10.0002 3.70641 10.3733 3.33331 10.8335 3.33331H15.8335C16.2937 3.33331 16.6668 3.70641 16.6668 4.16665V5.83331C16.6668 6.29355 16.2937 6.66665 15.8335 6.66665H10.8335C10.3733 6.66665 10.0002 6.29355 10.0002 5.83331V4.16665Z",stroke:o,strokeWidth:i})]}),x("g",{mask:"url(#mask0_277_1709)",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M0 0H20V20H0V0Z",fill:r})})]})}function Ng(e){const{width:t=20,height:n=20,fill:r="none",stroke:o=G.inactive,strokeWidth:i=1.5}=e;return ye("svg",{width:t,height:n,viewBox:`0 0 ${t} ${n}`,fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M12.266 5.83325H17.266M14.766 3.33325V8.33325M3.93262 4.16659C3.93262 3.94557 4.02041 3.73361 4.1767 3.57733C4.33298 3.42105 4.54494 3.33325 4.76595 3.33325H8.09928C8.3203 3.33325 8.53226 3.42105 8.68854 3.57733C8.84482 3.73361 8.93262 3.94557 8.93262 4.16659V7.49992C8.93262 7.72093 8.84482 7.93289 8.68854 8.08917C8.53226 8.24545 8.3203 8.33325 8.09928 8.33325H4.76595C4.54494 8.33325 4.33298 8.24545 4.1767 8.08917C4.02041 7.93289 3.93262 7.72093 3.93262 7.49992V4.16659ZM3.93262 12.4999C3.93262 12.2789 4.02041 12.0669 4.1767 11.9107C4.33298 11.7544 4.54494 11.6666 4.76595 11.6666H8.09928C8.3203 11.6666 8.53226 11.7544 8.68854 11.9107C8.84482 12.0669 8.93262 12.2789 8.93262 12.4999V15.8333C8.93262 16.0543 8.84482 16.2662 8.68854 16.4225C8.53226 16.5788 8.3203 16.6666 8.09928 16.6666H4.76595C4.54494 16.6666 4.33298 16.5788 4.1767 16.4225C4.02041 16.2662 3.93262 16.0543 3.93262 15.8333V12.4999ZM12.266 12.4999C12.266 12.2789 12.3537 12.0669 12.51 11.9107C12.6663 11.7544 12.8783 11.6666 13.0993 11.6666H16.4326C16.6536 11.6666 16.8656 11.7544 17.0219 11.9107C17.1782 12.0669 17.266 12.2789 17.266 12.4999V15.8333C17.266 16.0543 17.1782 16.2662 17.0219 16.4225C16.8656 16.5788 16.6536 16.6666 16.4326 16.6666H13.0993C12.8783 16.6666 12.6663 16.5788 12.51 16.4225C12.3537 16.2662 12.266 16.0543 12.266 15.8333V12.4999Z",stroke:o,strokeWidth:i}),x("mask",{id:"mask0_277_1610",maskUnits:"userSpaceOnUse",x:"0",y:"2",width:"20",height:"16",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M12.266 5.83325H17.266M14.766 3.33325V8.33325M3.93262 4.16659C3.93262 3.94557 4.02041 3.73361 4.1767 3.57733C4.33298 3.42105 4.54494 3.33325 4.76595 3.33325H8.09928C8.3203 3.33325 8.53226 3.42105 8.68854 3.57733C8.84482 3.73361 8.93262 3.94557 8.93262 4.16659V7.49992C8.93262 7.72093 8.84482 7.93289 8.68854 8.08917C8.53226 8.24545 8.3203 8.33325 8.09928 8.33325H4.76595C4.54494 8.33325 4.33298 8.24545 4.1767 8.08917C4.02041 7.93289 3.93262 7.72093 3.93262 7.49992V4.16659ZM3.93262 12.4999C3.93262 12.2789 4.02041 12.0669 4.1767 11.9107C4.33298 11.7544 4.54494 11.6666 4.76595 11.6666H8.09928C8.3203 11.6666 8.53226 11.7544 8.68854 11.9107C8.84482 12.0669 8.93262 12.2789 8.93262 12.4999V15.8333C8.93262 16.0543 8.84482 16.2662 8.68854 16.4225C8.53226 16.5788 8.3203 16.6666 8.09928 16.6666H4.76595C4.54494 16.6666 4.33298 16.5788 4.1767 16.4225C4.02041 16.2662 3.93262 16.0543 3.93262 15.8333V12.4999ZM12.266 12.4999C12.266 12.2789 12.3537 12.0669 12.51 11.9107C12.6663 11.7544 12.8783 11.6666 13.0993 11.6666H16.4326C16.6536 11.6666 16.8656 11.7544 17.0219 11.9107C17.1782 12.0669 17.266 12.2789 17.266 12.4999V15.8333C17.266 16.0543 17.1782 16.2662 17.0219 16.4225C16.8656 16.5788 16.6536 16.6666 16.4326 16.6666H13.0993C12.8783 16.6666 12.6663 16.5788 12.51 16.4225C12.3537 16.2662 12.266 16.0543 12.266 15.8333V12.4999Z",fill:"white"})}),x("g",{mask:"url(#mask0_277_1610)",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M0 0H20V20H0V0Z",fill:r})})]})}function Og(e){const{width:t=20,height:n=20,fill:r="none",stroke:o=G.inactive,strokeWidth:i=1.5}=e;return ye("svg",{width:t,height:n,viewBox:`0 0 ${t} ${n}`,fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11.2498 2.5L15.8332 7.1875M11.2498 2.5V6.35417C11.2498 6.8144 11.6229 7.1875 12.0832 7.1875H15.8332M11.2498 2.5H6.6665C5.28579 2.5 4.1665 3.61929 4.1665 5V15C4.1665 16.3807 5.28579 17.5 6.6665 17.5H13.3332C14.7139 17.5 15.8332 16.3807 15.8332 15V7.1875M7.49984 10.8333H12.4998M7.49984 14.1667H12.4998",stroke:o,strokeWidth:i}),x("mask",{id:"mask0_277_1639",maskUnits:"userSpaceOnUse",x:"2",y:"0",width:"16",height:"20",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11.2498 2.5L15.8332 7.1875M11.2498 2.5V6.35417C11.2498 6.8144 11.6229 7.1875 12.0832 7.1875H15.8332M11.2498 2.5H6.6665C5.28579 2.5 4.1665 3.61929 4.1665 5V15C4.1665 16.3807 5.28579 17.5 6.6665 17.5H13.3332C14.7139 17.5 15.8332 16.3807 15.8332 15V7.1875M7.49984 10.8333H12.4998M7.49984 14.1667H12.4998",fill:"white"})}),x("g",{mask:"url(#mask0_277_1639)",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M0 0H20V20H0V0Z",fill:r})})]})}function Lg(e){const{width:t=18,height:n=18,fill:r="none",stroke:o=G.inactive,strokeWidth:i=1.5}=e;return ye("svg",{width:`${t}`,height:`${n}`,viewBox:`0 0 ${t} ${n}`,fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.5 15.8333V15C2.5 13.159 3.99238 11.6666 5.83333 11.6666H9.16667C11.0076 11.6666 12.5 13.159 12.5 15V15.8333M12.5 9.16663C13.8807 9.16663 15 8.04734 15 6.66663C15 5.28591 13.8807 4.16663 12.5 4.16663M17.5 15.8333V15C17.5 13.159 16.0076 11.6666 14.1667 11.6666H13.75M10 6.66663C10 8.04734 8.88071 9.16663 7.5 9.16663C6.11929 9.16663 5 8.04734 5 6.66663C5 5.28591 6.11929 4.16663 7.5 4.16663C8.88071 4.16663 10 5.28591 10 6.66663Z",stroke:o,strokeWidth:1.5}),x("mask",{id:"mask0_277_1655",maskUnits:"userSpaceOnUse",x:"0",y:"0",width:"18",height:"18",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.5 15.8333V15C2.5 13.159 3.99238 11.6666 5.83333 11.6666H9.16667C11.0076 11.6666 12.5 13.159 12.5 15V15.8333M12.5 9.16663C13.8807 9.16663 15 8.04734 15 6.66663C15 5.28591 13.8807 4.16663 12.5 4.16663M17.5 15.8333V15C17.5 13.159 16.0076 11.6666 14.1667 11.6666H13.75M10 6.66663C10 8.04734 8.88071 9.16663 7.5 9.16663C6.11929 9.16663 5 8.04734 5 6.66663C5 5.28591 6.11929 4.16663 7.5 4.16663C8.88071 4.16663 10 5.28591 10 6.66663Z",fill:"white"})}),x("g",{mask:"url(#mask0_277_1655)",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M0 0H18V18H0V0Z",fill:r})})]})}function Hg(e){const{width:t=20,height:n=20,fill:r="none",stroke:o=G.inactive,strokeWidth:i=1.5}=e;return ye("svg",{width:t,height:n,viewBox:`0 0 ${t} ${n}`,fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M16.6666 7.77782V5.00004C16.6666 4.07957 15.9204 3.33337 14.9999 3.33337H12.2221M16.6666 7.77782H12.2221M16.6666 7.77782V12.2223M3.33325 7.77782V5.00004C3.33325 4.07957 4.07944 3.33337 4.99992 3.33337H7.7777M3.33325 7.77782H7.7777M3.33325 7.77782V12.2223M12.2221 7.77782H7.7777M12.2221 7.77782V3.33337M12.2221 7.77782V12.2223M7.7777 7.77782V3.33337M7.7777 7.77782V12.2223M16.6666 12.2223V15C16.6666 15.9205 15.9204 16.6667 14.9999 16.6667H12.2221M16.6666 12.2223H12.2221M3.33325 12.2223V15C3.33325 15.9205 4.07944 16.6667 4.99992 16.6667H7.7777M3.33325 12.2223H7.7777M12.2221 12.2223H7.7777M12.2221 12.2223V16.6667M7.7777 12.2223V16.6667M7.7777 3.33337H12.2221M7.7777 16.6667H12.2221",stroke:o,strokeWidth:i}),x("mask",{id:"mask0_277_1688",maskUnits:"userSpaceOnUse",x:"0",y:"1",width:"20",height:"18",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M16.6666 7.77782V5.00004C16.6666 4.07957 15.9204 3.33337 14.9999 3.33337H12.2221M16.6666 7.77782H12.2221M16.6666 7.77782V12.2223M3.33325 7.77782V5.00004C3.33325 4.07957 4.07944 3.33337 4.99992 3.33337H7.7777M3.33325 7.77782H7.7777M3.33325 7.77782V12.2223M12.2221 7.77782H7.7777M12.2221 7.77782V3.33337M12.2221 7.77782V12.2223M7.7777 7.77782V3.33337M7.7777 7.77782V12.2223M16.6666 12.2223V15C16.6666 15.9205 15.9204 16.6667 14.9999 16.6667H12.2221M16.6666 12.2223H12.2221M3.33325 12.2223V15C3.33325 15.9205 4.07944 16.6667 4.99992 16.6667H7.7777M3.33325 12.2223H7.7777M12.2221 12.2223H7.7777M12.2221 12.2223V16.6667M7.7777 12.2223V16.6667M7.7777 3.33337H12.2221M7.7777 16.6667H12.2221",fill:"white"})}),x("g",{mask:"url(#mask0_277_1688)",children:x("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M0 0H20V20H0V0Z",fill:r})})]})}function Dg(e){const{width:t=20,height:n=18,stroke:r=G.inactive,strokeWidth:o=0,fill:i=r}=e;return x("svg",{width:t,height:n,viewBox:`0 0 ${t} ${n}`,fill:"none",xmlns:"http://www.w3.org/2000/svg",children:x("path",{d:"M11.5625 0.25H19.0625C19.5803 0.25 20 0.669727 20 1.1875V7.4375C20 7.95527 19.5803 8.375 19.0625 8.375H11.5625C11.0447 8.375 10.625 7.95527 10.625 7.4375V1.1875C10.625 0.669727 11.0447 0.25 11.5625 0.25ZM8.4375 0.25H0.9375C0.419727 0.25 0 0.669727 0 1.1875V7.4375C0 7.95527 0.419727 8.375 0.9375 8.375H8.4375C8.95527 8.375 9.375 7.95527 9.375 7.4375V1.1875C9.375 0.669727 8.95527 0.25 8.4375 0.25ZM0 10.5625V16.8125C0 17.3303 0.419727 17.75 0.9375 17.75H8.4375C8.95527 17.75 9.375 17.3303 9.375 16.8125V10.5625C9.375 10.0447 8.95527 9.625 8.4375 9.625H0.9375C0.419727 9.625 0 10.0447 0 10.5625ZM11.5625 17.75H19.0625C19.5803 17.75 20 17.3303 20 16.8125V10.5625C20 10.0447 19.5803 9.625 19.0625 9.625H11.5625C11.0447 9.625 10.625 10.0447 10.625 10.5625V16.8125C10.625 17.3303 11.0447 17.75 11.5625 17.75Z",fill:i,stroke:r,strokeWidth:o})})}function Fg(e){const{stroke:t=G.inactive,strokeWidth:n=0,fill:r=t}=e;return x("svg",{version:"1.1",id:"svg2",xmlns:"http://www.w3.org/2000/svg",width:"20px",height:"20px",viewBox:"0 0 1200 1200",children:x("path",{fill:r,stroke:t,strokeWidth:n,id:"path4627",d:"M910.143,91.119l-16.916,81.053c-17.338,2.724-34.037,7.74-49.691,14.743 l-58.229-58.825l-66.309,53.661l45.354,69.303c-10.104,13.862-18.357,29.104-24.623,45.503l-82.85-0.374l-8.906,84.87l81.055,16.914 c2.723,17.329,7.746,33.897,14.742,49.545l-58.824,58.376l53.66,66.31l69.303-45.43c13.852,10.098,29.119,18.435,45.504,24.698 l-0.375,82.774l84.871,8.904l16.838-81.053c17.346-2.722,34.035-7.666,49.695-14.669l58.301,58.825l66.309-53.735l-45.428-69.229 c10.104-13.857,18.43-29.108,24.697-45.503l82.773,0.3l8.906-84.87l-81.053-16.765c-2.725-17.354-7.66-34.103-14.67-49.77 l58.824-58.227l-53.734-66.309l-69.229,45.354c-13.869-10.111-29.17-18.428-45.578-24.697l0.373-82.774L910.143,91.119 L910.143,91.119z M924.211,288.25c2.668,0.009,5.373,0.09,8.084,0.374c43.355,4.555,74.756,43.384,70.201,86.741 c-4.555,43.355-43.385,74.83-86.742,70.274c-43.355-4.555-74.83-43.384-70.275-86.739 C849.748,318.253,884.203,288.111,924.211,288.25L924.211,288.25z M315.23,295.21l-11.375,112.711 c-23.205,6.187-45.185,15.324-65.486,27.092l-87.714-71.696l-82.55,82.55l71.698,87.788c-11.768,20.308-20.91,42.272-27.092,65.484 L0,610.44v116.751l112.71,11.376c6.182,23.191,15.334,45.118,27.092,65.41l-71.698,87.789l82.55,82.55l87.789-71.697 c20.292,11.758,42.219,20.91,65.411,27.093l11.375,112.71h116.752l11.301-112.71c23.212-6.183,45.178-15.325,65.484-27.093 l87.788,71.697l82.55-82.55l-71.697-87.714c11.768-20.302,20.906-42.281,27.092-65.485l112.711-11.376V610.44L634.5,599.138 c-6.186-23.225-15.314-45.243-27.092-65.561l71.697-87.714l-82.55-82.549l-87.713,71.696 c-20.316-11.775-42.336-20.905-65.562-27.093l-11.301-112.71H315.23V295.21z M373.606,560.82 c59.649,0,107.996,48.348,107.996,107.996c0,59.647-48.347,107.994-107.996,107.994c-59.648,0-107.996-48.347-107.996-107.994 C265.61,609.168,313.958,560.82,373.606,560.82L373.606,560.82z M869.279,705.039l-11.9,59.273 c-12.188,1.993-23.873,5.653-34.877,10.776l-41.012-43.033l-46.553,39.292l31.883,50.667c-7.102,10.143-12.959,21.308-17.363,33.306 l-58.15-0.301l-6.287,62.118l56.955,12.35c1.912,12.678,5.41,24.851,10.328,36.298l-41.312,42.659l37.721,48.497l48.721-33.229 c9.736,7.386,20.441,13.454,31.957,18.037l-0.225,60.621l59.648,6.511l11.824-59.349c12.189-1.991,23.869-5.579,34.875-10.702 l41.014,43.033l46.625-39.291l-31.957-50.668c7.104-10.139,12.959-21.312,17.363-33.306l58.229,0.226l6.211-62.043l-56.953-12.35 c-1.914-12.695-5.402-24.911-10.328-36.372l41.311-42.585l-37.719-48.572l-48.646,33.229c-9.746-7.396-20.498-13.449-32.031-18.036 l0.299-60.546L869.279,705.039L869.279,705.039z M879.158,849.183c1.873,0.009,3.783,0.092,5.688,0.301 c30.473,3.331,52.521,31.745,49.32,63.465c-3.201,31.719-30.449,54.748-60.922,51.416s-52.596-31.746-49.395-63.466 C826.85,871.161,851.039,849.081,879.158,849.183L879.158,849.183z"})})}const Bg=_e.div` + background: ${G.primary}; + border: 1px solid ${G.primary}; + border-bottom: none; + border-top: none; + bottom: 0; + display: block; + left: 430px; + overflow-x: hidden; + overflow-y: auto; + position: fixed; + top: 50px; + opacity: 0; + visibility: hidden; + ${({isVisible:e})=>e?"opacity: 1; visibility: visible;":""} + width: 215px; + z-index: 1030; +`,Ug=_e.ul` + margin-top: 25px; + padding-left: 22px; + padding-right: 0px; +`;function $g(e){const{isOpen:t,children:n}=e;return x(Bg,{isVisible:t,"data-id":Kp,children:x(Ug,{children:n})})}const zg=_e.a` + width: 100%; + color: ${G.blue}; + cursor: pointer; + display: block; + font-size: 12px; + font-weight: ${({isActive:e})=>e?"600":"400"}; + line-height: 26px; + padding: 5px 10px 5px 8px; + position: relative; + white-space: nowrap; + text-decoration: none; + display: flex; + + &:hover { + font-weight: bold; + } +`,jg=_e.span` + display: block; + flex: 1; + max-width: none; + overflow: hidden; + text-overflow: ellipsis; +`,Vg=_e.li` + display: flex; +`;function le(e){const{id:t,dataId:n,children:r,label:o,onClick:i,href:a,className:l=""}=e,{activeSecondaryMenuItemId:s,setActiveSecondaryMenuItemId:u,setSecondaryMenuOpen:c,tertiaryMenuOpen:m,setTertiaryMenuOpen:p}=B.exports.useContext(Mo),g=!!r,v=s===t;return x(wa,{children:ye(Vg,{onClick:C=>{C.stopPropagation(),u(t),g?p(!0):(c(!1),i&&i())},className:l,"data-id":n,children:[ye(zg,{isActive:v,href:a,children:[x(jg,{children:o}),g&&x(Yp,{})]}),g&&v&&m&&x($g,{isOpen:!0,children:r})]})})}const Gg=_e.a` + width: 100%; + background-color: transparent; + background-color: ${({isActive:e})=>e?G.secondary:"transparent"}; + color: ${({isActive:e})=>e?G.white:G.text}; + cursor: pointer; + display: block; + font-size: 14px; + font-weight: ${({isActive:e})=>e?"600":"400"}; + line-height: 26px; + padding: 5px 10px 5px 8px; + position: relative; + white-space: nowrap; + text-decoration: none; + display: flex; + margin-top: 4px; + + &:hover { + font-weight: 600; + color: ${G.white}; + background-color: ${G.secondary}; + } +`,Wg=_e.span` + display: block; + flex: 1; + max-width: none; + overflow: hidden; + text-overflow: ellipsis; +`;function Xg(e){const{id:t,dataId:n,label:r,onClick:o,href:i,target:a,rel:l,className:s=""}=e,{activeTertiaryMenuItemId:u,setActiveTertiaryMenuItemId:c,setSecondaryMenuOpen:m}=B.exports.useContext(Mo);return x(Gg,{isActive:u===t,onClick:()=>{c(t),m(!1),o&&o()},href:i,className:s,rel:l,target:a,"data-id":n,children:x(Wg,{children:r})})}const No="superuser",Qg="managePages",Zg="editUsers",Yg="viewUsers",Kg="editUserProfile",qp="manageCategories",fu="editContents",Sa="validateContents",eh="manageResources",Jg="enterECR",At=(e,t)=>(t=t||[],e?Array.isArray(e)?e.some(n=>t.includes(n)):t.includes(e):!1),tn=(e,t)=>`${e}/${t}`,qg=(e,t)=>{const n=Object.keys(t);return n.length?n.reduce((r,o)=>r.replace(`:${o}`,t[o]),e):e},e2="homepage",t2="external",n2="noopener noreferrer",th="_blank",r2=e=>[...new Set(e.map(n=>n.pbcName))].map(n=>({parent:n,children:e.filter(r=>r.pbcName===n).map(r=>xt(xt({},r),r.target===t2?{url:r.addr,hrefTarget:th,rel:n2}:{url:`/${r.bundleCode}/${r.addr}`.replace(/(https?:\/\/)|(\/)+/g,"$1$2")}))})),nh="/dashboard",rh="/page",o2="/page/settings",i2="/page/configuration/:pageCode",oh="/page-template",ih="/widget",ah="/fragment",lh="/user",a2="/user/restrictions",sh="/profiletype",uh="/group",ch="/labels-languages",fh="/role",dh="/database",ph="/file-browser",hh="/component-repository",mh="/email-config",vh="/reloadConfiguration",gh={dashboard:nh,pages:[rh,oh],components:[ih,ah],users:[lh,fh,uh,sh],repository:hh,admin:[dh,ph,ch,mh,vh]};var du=function(e,t){return du=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,r){n.__proto__=r}||function(n,r){for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(n[o]=r[o])},du(e,t)};function St(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");du(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}var O=function(){return O=Object.assign||function(t){for(var n,r=1,o=arguments.length;r0}),n=[],r=0,o=t;r1)throw new RangeError("integer-width stems only accept a single optional option");o.options[0].replace(h2,function(s,u,c,m,p,g){if(u)t.minimumIntegerDigits=c.length;else{if(m&&p)throw new Error("We currently do not support maximum integer digits");if(g)throw new Error("We currently do not support exact integer digits")}return""});continue}if(bh.test(o.stem)){t.minimumIntegerDigits=o.stem.length;continue}if(Ih.test(o.stem)){if(o.options.length>1)throw new RangeError("Fraction-precision stems only accept a single optional option");o.stem.replace(Ih,function(s,u,c,m,p,g){return c==="*"?t.minimumFractionDigits=u.length:m&&m[0]==="#"?t.maximumFractionDigits=m.length:p&&g?(t.minimumFractionDigits=p.length,t.maximumFractionDigits=p.length+g.length):(t.minimumFractionDigits=u.length,t.maximumFractionDigits=u.length),""});var i=o.options[0];i==="w"?t=O(O({},t),{trailingZeroDisplay:"stripIfInteger"}):i&&(t=O(O({},t),Ah(i)));continue}if(Ph.test(o.stem)){t=O(O({},t),Ah(o.stem));continue}var a=Mh(o.stem);a&&(t=O(O({},t),a));var l=m2(o.stem);l&&(t=O(O({},t),l))}return t}var xa={AX:["H"],BQ:["H"],CP:["H"],CZ:["H"],DK:["H"],FI:["H"],ID:["H"],IS:["H"],ML:["H"],NE:["H"],RU:["H"],SE:["H"],SJ:["H"],SK:["H"],AS:["h","H"],BT:["h","H"],DJ:["h","H"],ER:["h","H"],GH:["h","H"],IN:["h","H"],LS:["h","H"],PG:["h","H"],PW:["h","H"],SO:["h","H"],TO:["h","H"],VU:["h","H"],WS:["h","H"],"001":["H","h"],AL:["h","H","hB"],TD:["h","H","hB"],"ca-ES":["H","h","hB"],CF:["H","h","hB"],CM:["H","h","hB"],"fr-CA":["H","h","hB"],"gl-ES":["H","h","hB"],"it-CH":["H","h","hB"],"it-IT":["H","h","hB"],LU:["H","h","hB"],NP:["H","h","hB"],PF:["H","h","hB"],SC:["H","h","hB"],SM:["H","h","hB"],SN:["H","h","hB"],TF:["H","h","hB"],VA:["H","h","hB"],CY:["h","H","hb","hB"],GR:["h","H","hb","hB"],CO:["h","H","hB","hb"],DO:["h","H","hB","hb"],KP:["h","H","hB","hb"],KR:["h","H","hB","hb"],NA:["h","H","hB","hb"],PA:["h","H","hB","hb"],PR:["h","H","hB","hb"],VE:["h","H","hB","hb"],AC:["H","h","hb","hB"],AI:["H","h","hb","hB"],BW:["H","h","hb","hB"],BZ:["H","h","hb","hB"],CC:["H","h","hb","hB"],CK:["H","h","hb","hB"],CX:["H","h","hb","hB"],DG:["H","h","hb","hB"],FK:["H","h","hb","hB"],GB:["H","h","hb","hB"],GG:["H","h","hb","hB"],GI:["H","h","hb","hB"],IE:["H","h","hb","hB"],IM:["H","h","hb","hB"],IO:["H","h","hb","hB"],JE:["H","h","hb","hB"],LT:["H","h","hb","hB"],MK:["H","h","hb","hB"],MN:["H","h","hb","hB"],MS:["H","h","hb","hB"],NF:["H","h","hb","hB"],NG:["H","h","hb","hB"],NR:["H","h","hb","hB"],NU:["H","h","hb","hB"],PN:["H","h","hb","hB"],SH:["H","h","hb","hB"],SX:["H","h","hb","hB"],TA:["H","h","hb","hB"],ZA:["H","h","hb","hB"],"af-ZA":["H","h","hB","hb"],AR:["H","h","hB","hb"],CL:["H","h","hB","hb"],CR:["H","h","hB","hb"],CU:["H","h","hB","hb"],EA:["H","h","hB","hb"],"es-BO":["H","h","hB","hb"],"es-BR":["H","h","hB","hb"],"es-EC":["H","h","hB","hb"],"es-ES":["H","h","hB","hb"],"es-GQ":["H","h","hB","hb"],"es-PE":["H","h","hB","hb"],GT:["H","h","hB","hb"],HN:["H","h","hB","hb"],IC:["H","h","hB","hb"],KG:["H","h","hB","hb"],KM:["H","h","hB","hb"],LK:["H","h","hB","hb"],MA:["H","h","hB","hb"],MX:["H","h","hB","hb"],NI:["H","h","hB","hb"],PY:["H","h","hB","hb"],SV:["H","h","hB","hb"],UY:["H","h","hB","hb"],JP:["H","h","K"],AD:["H","hB"],AM:["H","hB"],AO:["H","hB"],AT:["H","hB"],AW:["H","hB"],BE:["H","hB"],BF:["H","hB"],BJ:["H","hB"],BL:["H","hB"],BR:["H","hB"],CG:["H","hB"],CI:["H","hB"],CV:["H","hB"],DE:["H","hB"],EE:["H","hB"],FR:["H","hB"],GA:["H","hB"],GF:["H","hB"],GN:["H","hB"],GP:["H","hB"],GW:["H","hB"],HR:["H","hB"],IL:["H","hB"],IT:["H","hB"],KZ:["H","hB"],MC:["H","hB"],MD:["H","hB"],MF:["H","hB"],MQ:["H","hB"],MZ:["H","hB"],NC:["H","hB"],NL:["H","hB"],PM:["H","hB"],PT:["H","hB"],RE:["H","hB"],RO:["H","hB"],SI:["H","hB"],SR:["H","hB"],ST:["H","hB"],TG:["H","hB"],TR:["H","hB"],WF:["H","hB"],YT:["H","hB"],BD:["h","hB","H"],PK:["h","hB","H"],AZ:["H","hB","h"],BA:["H","hB","h"],BG:["H","hB","h"],CH:["H","hB","h"],GE:["H","hB","h"],LI:["H","hB","h"],ME:["H","hB","h"],RS:["H","hB","h"],UA:["H","hB","h"],UZ:["H","hB","h"],XK:["H","hB","h"],AG:["h","hb","H","hB"],AU:["h","hb","H","hB"],BB:["h","hb","H","hB"],BM:["h","hb","H","hB"],BS:["h","hb","H","hB"],CA:["h","hb","H","hB"],DM:["h","hb","H","hB"],"en-001":["h","hb","H","hB"],FJ:["h","hb","H","hB"],FM:["h","hb","H","hB"],GD:["h","hb","H","hB"],GM:["h","hb","H","hB"],GU:["h","hb","H","hB"],GY:["h","hb","H","hB"],JM:["h","hb","H","hB"],KI:["h","hb","H","hB"],KN:["h","hb","H","hB"],KY:["h","hb","H","hB"],LC:["h","hb","H","hB"],LR:["h","hb","H","hB"],MH:["h","hb","H","hB"],MP:["h","hb","H","hB"],MW:["h","hb","H","hB"],NZ:["h","hb","H","hB"],SB:["h","hb","H","hB"],SG:["h","hb","H","hB"],SL:["h","hb","H","hB"],SS:["h","hb","H","hB"],SZ:["h","hb","H","hB"],TC:["h","hb","H","hB"],TT:["h","hb","H","hB"],UM:["h","hb","H","hB"],US:["h","hb","H","hB"],VC:["h","hb","H","hB"],VG:["h","hb","H","hB"],VI:["h","hb","H","hB"],ZM:["h","hb","H","hB"],BO:["H","hB","h","hb"],EC:["H","hB","h","hb"],ES:["H","hB","h","hb"],GQ:["H","hB","h","hb"],PE:["H","hB","h","hb"],AE:["h","hB","hb","H"],"ar-001":["h","hB","hb","H"],BH:["h","hB","hb","H"],DZ:["h","hB","hb","H"],EG:["h","hB","hb","H"],EH:["h","hB","hb","H"],HK:["h","hB","hb","H"],IQ:["h","hB","hb","H"],JO:["h","hB","hb","H"],KW:["h","hB","hb","H"],LB:["h","hB","hb","H"],LY:["h","hB","hb","H"],MO:["h","hB","hb","H"],MR:["h","hB","hb","H"],OM:["h","hB","hb","H"],PH:["h","hB","hb","H"],PS:["h","hB","hb","H"],QA:["h","hB","hb","H"],SA:["h","hB","hb","H"],SD:["h","hB","hb","H"],SY:["h","hB","hb","H"],TN:["h","hB","hb","H"],YE:["h","hB","hb","H"],AF:["H","hb","hB","h"],LA:["H","hb","hB","h"],CN:["H","hB","hb","h"],LV:["H","hB","hb","h"],TL:["H","hB","hb","h"],"zu-ZA":["H","hB","hb","h"],CD:["hB","H"],IR:["hB","H"],"hi-IN":["hB","h","H"],"kn-IN":["hB","h","H"],"ml-IN":["hB","h","H"],"te-IN":["hB","h","H"],KH:["hB","h","H","hb"],"ta-IN":["hB","h","hb","H"],BN:["hb","hB","h","H"],MY:["hb","hB","h","H"],ET:["hB","hb","h","H"],"gu-IN":["hB","hb","h","H"],"mr-IN":["hB","hb","h","H"],"pa-IN":["hB","hb","h","H"],TW:["hB","hb","h","H"],KE:["hB","hb","H","h"],MM:["hB","hb","H","h"],TZ:["hB","hb","H","h"],UG:["hB","hb","H","h"]};function g2(e,t){for(var n="",r=0;r>1),s="a",u=y2(t);for((u=="H"||u=="k")&&(l=0);l-- >0;)n+=s;for(;a-- >0;)n=u+n}else o==="J"?n+="H":n+=o}return n}function y2(e){var t=e.hourCycle;if(t===void 0&&e.hourCycles&&e.hourCycles.length&&(t=e.hourCycles[0]),t)switch(t){case"h24":return"k";case"h23":return"H";case"h12":return"h";case"h11":return"K";default:throw new Error("Invalid hourCycle")}var n=e.language,r;n!=="root"&&(r=e.maximize().region);var o=xa[r||""]||xa[n||""]||xa["".concat(n,"-001")]||xa["001"];return o[0]}var mu,E2=new RegExp("^".concat(Rh.source,"*")),w2=new RegExp("".concat(Rh.source,"*$"));function Z(e,t){return{start:e,end:t}}var S2=!!String.prototype.startsWith,x2=!!String.fromCodePoint,C2=!!Object.fromEntries,T2=!!String.prototype.codePointAt,k2=!!String.prototype.trimStart,_2=!!String.prototype.trimEnd,R2=!!Number.isSafeInteger,I2=R2?Number.isSafeInteger:function(e){return typeof e=="number"&&isFinite(e)&&Math.floor(e)===e&&Math.abs(e)<=9007199254740991},vu=!0;try{var P2=Dh("([^\\p{White_Space}\\p{Pattern_Syntax}]*)","yu");vu=((mu=P2.exec("a"))===null||mu===void 0?void 0:mu[0])==="a"}catch{vu=!1}var Oh=S2?function(t,n,r){return t.startsWith(n,r)}:function(t,n,r){return t.slice(r,r+n.length)===n},gu=x2?String.fromCodePoint:function(){for(var t=[],n=0;ni;){if(a=t[i++],a>1114111)throw RangeError(a+" is not a valid code point");r+=a<65536?String.fromCharCode(a):String.fromCharCode(((a-=65536)>>10)+55296,a%1024+56320)}return r},Lh=C2?Object.fromEntries:function(t){for(var n={},r=0,o=t;r=r)){var o=t.charCodeAt(n),i;return o<55296||o>56319||n+1===r||(i=t.charCodeAt(n+1))<56320||i>57343?o:(o-55296<<10)+(i-56320)+65536}},b2=k2?function(t){return t.trimStart()}:function(t){return t.replace(E2,"")},A2=_2?function(t){return t.trimEnd()}:function(t){return t.replace(w2,"")};function Dh(e,t){return new RegExp(e,t)}var yu;if(vu){var Fh=Dh("([^\\p{White_Space}\\p{Pattern_Syntax}]*)","yu");yu=function(t,n){var r;Fh.lastIndex=n;var o=Fh.exec(t);return(r=o[1])!==null&&r!==void 0?r:""}}else yu=function(t,n){for(var r=[];;){var o=Hh(t,n);if(o===void 0||Bh(o)||L2(o))break;r.push(o),n+=o>=65536?2:1}return gu.apply(void 0,r)};var M2=function(){function e(t,n){n===void 0&&(n={}),this.message=t,this.position={offset:0,line:1,column:1},this.ignoreTag=!!n.ignoreTag,this.locale=n.locale,this.requiresOtherClause=!!n.requiresOtherClause,this.shouldParseSkeletons=!!n.shouldParseSkeletons}return e.prototype.parse=function(){if(this.offset()!==0)throw Error("parser can only be used once");return this.parseMessage(0,"",!1)},e.prototype.parseMessage=function(t,n,r){for(var o=[];!this.isEOF();){var i=this.char();if(i===123){var a=this.parseArgument(t,r);if(a.err)return a;o.push(a.val)}else{if(i===125&&t>0)break;if(i===35&&(n==="plural"||n==="selectordinal")){var l=this.clonePosition();this.bump(),o.push({type:ce.pound,location:Z(l,this.clonePosition())})}else if(i===60&&!this.ignoreTag&&this.peek()===47){if(r)break;return this.error(W.UNMATCHED_CLOSING_TAG,Z(this.clonePosition(),this.clonePosition()))}else if(i===60&&!this.ignoreTag&&Eu(this.peek()||0)){var a=this.parseTag(t,n);if(a.err)return a;o.push(a.val)}else{var a=this.parseLiteral(t,n);if(a.err)return a;o.push(a.val)}}}return{val:o,err:null}},e.prototype.parseTag=function(t,n){var r=this.clonePosition();this.bump();var o=this.parseTagName();if(this.bumpSpace(),this.bumpIf("/>"))return{val:{type:ce.literal,value:"<".concat(o,"/>"),location:Z(r,this.clonePosition())},err:null};if(this.bumpIf(">")){var i=this.parseMessage(t+1,n,!0);if(i.err)return i;var a=i.val,l=this.clonePosition();if(this.bumpIf("")?{val:{type:ce.tag,value:o,children:a,location:Z(r,this.clonePosition())},err:null}:this.error(W.INVALID_TAG,Z(l,this.clonePosition())))}else return this.error(W.UNCLOSED_TAG,Z(r,this.clonePosition()))}else return this.error(W.INVALID_TAG,Z(r,this.clonePosition()))},e.prototype.parseTagName=function(){var t=this.offset();for(this.bump();!this.isEOF()&&O2(this.char());)this.bump();return this.message.slice(t,this.offset())},e.prototype.parseLiteral=function(t,n){for(var r=this.clonePosition(),o="";;){var i=this.tryParseQuote(n);if(i){o+=i;continue}var a=this.tryParseUnquoted(t,n);if(a){o+=a;continue}var l=this.tryParseLeftAngleBracket();if(l){o+=l;continue}break}var s=Z(r,this.clonePosition());return{val:{type:ce.literal,value:o,location:s},err:null}},e.prototype.tryParseLeftAngleBracket=function(){return!this.isEOF()&&this.char()===60&&(this.ignoreTag||!N2(this.peek()||0))?(this.bump(),"<"):null},e.prototype.tryParseQuote=function(t){if(this.isEOF()||this.char()!==39)return null;switch(this.peek()){case 39:return this.bump(),this.bump(),"'";case 123:case 60:case 62:case 125:break;case 35:if(t==="plural"||t==="selectordinal")break;return null;default:return null}this.bump();var n=[this.char()];for(this.bump();!this.isEOF();){var r=this.char();if(r===39)if(this.peek()===39)n.push(39),this.bump();else{this.bump();break}else n.push(r);this.bump()}return gu.apply(void 0,n)},e.prototype.tryParseUnquoted=function(t,n){if(this.isEOF())return null;var r=this.char();return r===60||r===123||r===35&&(n==="plural"||n==="selectordinal")||r===125&&t>0?null:(this.bump(),gu(r))},e.prototype.parseArgument=function(t,n){var r=this.clonePosition();if(this.bump(),this.bumpSpace(),this.isEOF())return this.error(W.EXPECT_ARGUMENT_CLOSING_BRACE,Z(r,this.clonePosition()));if(this.char()===125)return this.bump(),this.error(W.EMPTY_ARGUMENT,Z(r,this.clonePosition()));var o=this.parseIdentifierIfPossible().value;if(!o)return this.error(W.MALFORMED_ARGUMENT,Z(r,this.clonePosition()));if(this.bumpSpace(),this.isEOF())return this.error(W.EXPECT_ARGUMENT_CLOSING_BRACE,Z(r,this.clonePosition()));switch(this.char()){case 125:return this.bump(),{val:{type:ce.argument,value:o,location:Z(r,this.clonePosition())},err:null};case 44:return this.bump(),this.bumpSpace(),this.isEOF()?this.error(W.EXPECT_ARGUMENT_CLOSING_BRACE,Z(r,this.clonePosition())):this.parseArgumentOptions(t,n,o,r);default:return this.error(W.MALFORMED_ARGUMENT,Z(r,this.clonePosition()))}},e.prototype.parseIdentifierIfPossible=function(){var t=this.clonePosition(),n=this.offset(),r=yu(this.message,n),o=n+r.length;this.bumpTo(o);var i=this.clonePosition(),a=Z(t,i);return{value:r,location:a}},e.prototype.parseArgumentOptions=function(t,n,r,o){var i,a=this.clonePosition(),l=this.parseIdentifierIfPossible().value,s=this.clonePosition();switch(l){case"":return this.error(W.EXPECT_ARGUMENT_TYPE,Z(a,s));case"number":case"date":case"time":{this.bumpSpace();var u=null;if(this.bumpIf(",")){this.bumpSpace();var c=this.clonePosition(),m=this.parseSimpleArgStyleIfPossible();if(m.err)return m;var p=A2(m.val);if(p.length===0)return this.error(W.EXPECT_ARGUMENT_STYLE,Z(this.clonePosition(),this.clonePosition()));var g=Z(c,this.clonePosition());u={style:p,styleLocation:g}}var v=this.tryParseArgumentClose(o);if(v.err)return v;var S=Z(o,this.clonePosition());if(u&&Oh(u==null?void 0:u.style,"::",0)){var C=b2(u.style.slice(2));if(l==="number"){var m=this.parseNumberSkeletonFromString(C,u.styleLocation);return m.err?m:{val:{type:ce.number,value:r,location:S,style:m.val},err:null}}else{if(C.length===0)return this.error(W.EXPECT_DATE_TIME_SKELETON,S);var d=C;this.locale&&(d=g2(C,this.locale));var p={type:xr.dateTime,pattern:d,location:u.styleLocation,parsedOptions:this.shouldParseSkeletons?c2(d):{}},f=l==="date"?ce.date:ce.time;return{val:{type:f,value:r,location:S,style:p},err:null}}}return{val:{type:l==="number"?ce.number:l==="date"?ce.date:ce.time,value:r,location:S,style:(i=u==null?void 0:u.style)!==null&&i!==void 0?i:null},err:null}}case"plural":case"selectordinal":case"select":{var h=this.clonePosition();if(this.bumpSpace(),!this.bumpIf(","))return this.error(W.EXPECT_SELECT_ARGUMENT_OPTIONS,Z(h,O({},h)));this.bumpSpace();var w=this.parseIdentifierIfPossible(),E=0;if(l!=="select"&&w.value==="offset"){if(!this.bumpIf(":"))return this.error(W.EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE,Z(this.clonePosition(),this.clonePosition()));this.bumpSpace();var m=this.tryParseDecimalInteger(W.EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE,W.INVALID_PLURAL_ARGUMENT_OFFSET_VALUE);if(m.err)return m;this.bumpSpace(),w=this.parseIdentifierIfPossible(),E=m.val}var _=this.tryParsePluralOrSelectOptions(t,l,n,w);if(_.err)return _;var v=this.tryParseArgumentClose(o);if(v.err)return v;var A=Z(o,this.clonePosition());return l==="select"?{val:{type:ce.select,value:r,options:Lh(_.val),location:A},err:null}:{val:{type:ce.plural,value:r,options:Lh(_.val),offset:E,pluralType:l==="plural"?"cardinal":"ordinal",location:A},err:null}}default:return this.error(W.INVALID_ARGUMENT_TYPE,Z(a,s))}},e.prototype.tryParseArgumentClose=function(t){return this.isEOF()||this.char()!==125?this.error(W.EXPECT_ARGUMENT_CLOSING_BRACE,Z(t,this.clonePosition())):(this.bump(),{val:!0,err:null})},e.prototype.parseSimpleArgStyleIfPossible=function(){for(var t=0,n=this.clonePosition();!this.isEOF();){var r=this.char();switch(r){case 39:{this.bump();var o=this.clonePosition();if(!this.bumpUntil("'"))return this.error(W.UNCLOSED_QUOTE_IN_ARGUMENT_STYLE,Z(o,this.clonePosition()));this.bump();break}case 123:{t+=1,this.bump();break}case 125:{if(t>0)t-=1;else return{val:this.message.slice(n.offset,this.offset()),err:null};break}default:this.bump();break}}return{val:this.message.slice(n.offset,this.offset()),err:null}},e.prototype.parseNumberSkeletonFromString=function(t,n){var r=[];try{r=d2(t)}catch{return this.error(W.INVALID_NUMBER_SKELETON,n)}return{val:{type:xr.number,tokens:r,location:n,parsedOptions:this.shouldParseSkeletons?v2(r):{}},err:null}},e.prototype.tryParsePluralOrSelectOptions=function(t,n,r,o){for(var i,a=!1,l=[],s=new Set,u=o.value,c=o.location;;){if(u.length===0){var m=this.clonePosition();if(n!=="select"&&this.bumpIf("=")){var p=this.tryParseDecimalInteger(W.EXPECT_PLURAL_ARGUMENT_SELECTOR,W.INVALID_PLURAL_ARGUMENT_SELECTOR);if(p.err)return p;c=Z(m,this.clonePosition()),u=this.message.slice(m.offset,this.offset())}else break}if(s.has(u))return this.error(n==="select"?W.DUPLICATE_SELECT_ARGUMENT_SELECTOR:W.DUPLICATE_PLURAL_ARGUMENT_SELECTOR,c);u==="other"&&(a=!0),this.bumpSpace();var g=this.clonePosition();if(!this.bumpIf("{"))return this.error(n==="select"?W.EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT:W.EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT,Z(this.clonePosition(),this.clonePosition()));var v=this.parseMessage(t+1,n,r);if(v.err)return v;var S=this.tryParseArgumentClose(g);if(S.err)return S;l.push([u,{value:v.val,location:Z(g,this.clonePosition())}]),s.add(u),this.bumpSpace(),i=this.parseIdentifierIfPossible(),u=i.value,c=i.location}return l.length===0?this.error(n==="select"?W.EXPECT_SELECT_ARGUMENT_SELECTOR:W.EXPECT_PLURAL_ARGUMENT_SELECTOR,Z(this.clonePosition(),this.clonePosition())):this.requiresOtherClause&&!a?this.error(W.MISSING_OTHER_CLAUSE,Z(this.clonePosition(),this.clonePosition())):{val:l,err:null}},e.prototype.tryParseDecimalInteger=function(t,n){var r=1,o=this.clonePosition();this.bumpIf("+")||this.bumpIf("-")&&(r=-1);for(var i=!1,a=0;!this.isEOF();){var l=this.char();if(l>=48&&l<=57)i=!0,a=a*10+(l-48),this.bump();else break}var s=Z(o,this.clonePosition());return i?(a*=r,I2(a)?{val:a,err:null}:this.error(n,s)):this.error(t,s)},e.prototype.offset=function(){return this.position.offset},e.prototype.isEOF=function(){return this.offset()===this.message.length},e.prototype.clonePosition=function(){return{offset:this.position.offset,line:this.position.line,column:this.position.column}},e.prototype.char=function(){var t=this.position.offset;if(t>=this.message.length)throw Error("out of bound");var n=Hh(this.message,t);if(n===void 0)throw Error("Offset ".concat(t," is at invalid UTF-16 code unit boundary"));return n},e.prototype.error=function(t,n){return{val:null,err:{kind:t,message:this.message,location:n}}},e.prototype.bump=function(){if(!this.isEOF()){var t=this.char();t===10?(this.position.line+=1,this.position.column=1,this.position.offset+=1):(this.position.column+=1,this.position.offset+=t<65536?1:2)}},e.prototype.bumpIf=function(t){if(Oh(this.message,t,this.offset())){for(var n=0;n=0?(this.bumpTo(r),!0):(this.bumpTo(this.message.length),!1)},e.prototype.bumpTo=function(t){if(this.offset()>t)throw Error("targetOffset ".concat(t," must be greater than or equal to the current offset ").concat(this.offset()));for(t=Math.min(t,this.message.length);;){var n=this.offset();if(n===t)break;if(n>t)throw Error("targetOffset ".concat(t," is at invalid UTF-16 code unit boundary"));if(this.bump(),this.isEOF())break}},e.prototype.bumpSpace=function(){for(;!this.isEOF()&&Bh(this.char());)this.bump()},e.prototype.peek=function(){if(this.isEOF())return null;var t=this.char(),n=this.offset(),r=this.message.charCodeAt(n+(t>=65536?2:1));return r!=null?r:null},e}();function Eu(e){return e>=97&&e<=122||e>=65&&e<=90}function N2(e){return Eu(e)||e===47}function O2(e){return e===45||e===46||e>=48&&e<=57||e===95||e>=97&&e<=122||e>=65&&e<=90||e==183||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=893||e>=895&&e<=8191||e>=8204&&e<=8205||e>=8255&&e<=8256||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}function Bh(e){return e>=9&&e<=13||e===32||e===133||e>=8206&&e<=8207||e===8232||e===8233}function L2(e){return e>=33&&e<=35||e===36||e>=37&&e<=39||e===40||e===41||e===42||e===43||e===44||e===45||e>=46&&e<=47||e>=58&&e<=59||e>=60&&e<=62||e>=63&&e<=64||e===91||e===92||e===93||e===94||e===96||e===123||e===124||e===125||e===126||e===161||e>=162&&e<=165||e===166||e===167||e===169||e===171||e===172||e===174||e===176||e===177||e===182||e===187||e===191||e===215||e===247||e>=8208&&e<=8213||e>=8214&&e<=8215||e===8216||e===8217||e===8218||e>=8219&&e<=8220||e===8221||e===8222||e===8223||e>=8224&&e<=8231||e>=8240&&e<=8248||e===8249||e===8250||e>=8251&&e<=8254||e>=8257&&e<=8259||e===8260||e===8261||e===8262||e>=8263&&e<=8273||e===8274||e===8275||e>=8277&&e<=8286||e>=8592&&e<=8596||e>=8597&&e<=8601||e>=8602&&e<=8603||e>=8604&&e<=8607||e===8608||e>=8609&&e<=8610||e===8611||e>=8612&&e<=8613||e===8614||e>=8615&&e<=8621||e===8622||e>=8623&&e<=8653||e>=8654&&e<=8655||e>=8656&&e<=8657||e===8658||e===8659||e===8660||e>=8661&&e<=8691||e>=8692&&e<=8959||e>=8960&&e<=8967||e===8968||e===8969||e===8970||e===8971||e>=8972&&e<=8991||e>=8992&&e<=8993||e>=8994&&e<=9e3||e===9001||e===9002||e>=9003&&e<=9083||e===9084||e>=9085&&e<=9114||e>=9115&&e<=9139||e>=9140&&e<=9179||e>=9180&&e<=9185||e>=9186&&e<=9254||e>=9255&&e<=9279||e>=9280&&e<=9290||e>=9291&&e<=9311||e>=9472&&e<=9654||e===9655||e>=9656&&e<=9664||e===9665||e>=9666&&e<=9719||e>=9720&&e<=9727||e>=9728&&e<=9838||e===9839||e>=9840&&e<=10087||e===10088||e===10089||e===10090||e===10091||e===10092||e===10093||e===10094||e===10095||e===10096||e===10097||e===10098||e===10099||e===10100||e===10101||e>=10132&&e<=10175||e>=10176&&e<=10180||e===10181||e===10182||e>=10183&&e<=10213||e===10214||e===10215||e===10216||e===10217||e===10218||e===10219||e===10220||e===10221||e===10222||e===10223||e>=10224&&e<=10239||e>=10240&&e<=10495||e>=10496&&e<=10626||e===10627||e===10628||e===10629||e===10630||e===10631||e===10632||e===10633||e===10634||e===10635||e===10636||e===10637||e===10638||e===10639||e===10640||e===10641||e===10642||e===10643||e===10644||e===10645||e===10646||e===10647||e===10648||e>=10649&&e<=10711||e===10712||e===10713||e===10714||e===10715||e>=10716&&e<=10747||e===10748||e===10749||e>=10750&&e<=11007||e>=11008&&e<=11055||e>=11056&&e<=11076||e>=11077&&e<=11078||e>=11079&&e<=11084||e>=11085&&e<=11123||e>=11124&&e<=11125||e>=11126&&e<=11157||e===11158||e>=11159&&e<=11263||e>=11776&&e<=11777||e===11778||e===11779||e===11780||e===11781||e>=11782&&e<=11784||e===11785||e===11786||e===11787||e===11788||e===11789||e>=11790&&e<=11798||e===11799||e>=11800&&e<=11801||e===11802||e===11803||e===11804||e===11805||e>=11806&&e<=11807||e===11808||e===11809||e===11810||e===11811||e===11812||e===11813||e===11814||e===11815||e===11816||e===11817||e>=11818&&e<=11822||e===11823||e>=11824&&e<=11833||e>=11834&&e<=11835||e>=11836&&e<=11839||e===11840||e===11841||e===11842||e>=11843&&e<=11855||e>=11856&&e<=11857||e===11858||e>=11859&&e<=11903||e>=12289&&e<=12291||e===12296||e===12297||e===12298||e===12299||e===12300||e===12301||e===12302||e===12303||e===12304||e===12305||e>=12306&&e<=12307||e===12308||e===12309||e===12310||e===12311||e===12312||e===12313||e===12314||e===12315||e===12316||e===12317||e>=12318&&e<=12319||e===12320||e===12336||e===64830||e===64831||e>=65093&&e<=65094}function wu(e){e.forEach(function(t){if(delete t.location,Ch(t)||Th(t))for(var n in t.options)delete t.options[n].location,wu(t.options[n].value);else wh(t)&&_h(t.style)||(Sh(t)||xh(t))&&hu(t.style)?delete t.style.location:kh(t)&&wu(t.children)})}function H2(e,t){t===void 0&&(t={}),t=O({shouldParseSkeletons:!0,requiresOtherClause:!0},t);var n=new M2(e,t).parse();if(n.err){var r=SyntaxError(W[n.err.kind]);throw r.location=n.err.location,r.originalMessage=n.err.message,r}return t!=null&&t.captureLocation||wu(n.val),n.val}function zt(e,t){var n=t&&t.cache?t.cache:z2,r=t&&t.serializer?t.serializer:$2,o=t&&t.strategy?t.strategy:F2;return o(e,{cache:n,serializer:r})}function D2(e){return e==null||typeof e=="number"||typeof e=="boolean"}function Uh(e,t,n,r){var o=D2(r)?r:n(r),i=t.get(o);return typeof i=="undefined"&&(i=e.call(this,r),t.set(o,i)),i}function $h(e,t,n){var r=Array.prototype.slice.call(arguments,3),o=n(r),i=t.get(o);return typeof i=="undefined"&&(i=e.apply(this,r),t.set(o,i)),i}function Su(e,t,n,r,o){return n.bind(t,e,r,o)}function F2(e,t){var n=e.length===1?Uh:$h;return Su(e,this,n,t.cache.create(),t.serializer)}function B2(e,t){return Su(e,this,$h,t.cache.create(),t.serializer)}function U2(e,t){return Su(e,this,Uh,t.cache.create(),t.serializer)}var $2=function(){return JSON.stringify(arguments)};function xu(){this.cache=Object.create(null)}xu.prototype.get=function(e){return this.cache[e]},xu.prototype.set=function(e,t){this.cache[e]=t};var z2={create:function(){return new xu}},jt={variadic:B2,monadic:U2},Vt;(function(e){e.MISSING_VALUE="MISSING_VALUE",e.INVALID_VALUE="INVALID_VALUE",e.MISSING_INTL_API="MISSING_INTL_API"})(Vt||(Vt={}));var _n=function(e){St(t,e);function t(n,r,o){var i=e.call(this,n)||this;return i.code=r,i.originalMessage=o,i}return t.prototype.toString=function(){return"[formatjs Error: ".concat(this.code,"] ").concat(this.message)},t}(Error),zh=function(e){St(t,e);function t(n,r,o,i){return e.call(this,'Invalid values for "'.concat(n,'": "').concat(r,'". Options are "').concat(Object.keys(o).join('", "'),'"'),Vt.INVALID_VALUE,i)||this}return t}(_n),j2=function(e){St(t,e);function t(n,r,o){return e.call(this,'Value for "'.concat(n,'" must be of type ').concat(r),Vt.INVALID_VALUE,o)||this}return t}(_n),V2=function(e){St(t,e);function t(n,r){return e.call(this,'The intl string context variable "'.concat(n,'" was not provided to the string "').concat(r,'"'),Vt.MISSING_VALUE,r)||this}return t}(_n),Ke;(function(e){e[e.literal=0]="literal",e[e.object=1]="object"})(Ke||(Ke={}));function G2(e){return e.length<2?e:e.reduce(function(t,n){var r=t[t.length-1];return!r||r.type!==Ke.literal||n.type!==Ke.literal?t.push(n):r.value+=n.value,t},[])}function jh(e){return typeof e=="function"}function Ca(e,t,n,r,o,i,a){if(e.length===1&&Eh(e[0]))return[{type:Ke.literal,value:e[0].value}];for(var l=[],s=0,u=e;s0?new Intl.Locale(n[0]):new Intl.Locale(typeof t=="string"?t:t[0])}},e.__parse=H2,e.formats={number:{integer:{maximumFractionDigits:0},currency:{style:"currency"},percent:{style:"percent"}},date:{short:{month:"numeric",day:"numeric",year:"2-digit"},medium:{month:"short",day:"numeric",year:"numeric"},long:{month:"long",day:"numeric",year:"numeric"},full:{weekday:"long",month:"long",day:"numeric",year:"numeric"}},time:{short:{hour:"numeric",minute:"numeric"},medium:{hour:"numeric",minute:"numeric",second:"numeric"},long:{hour:"numeric",minute:"numeric",second:"numeric",timeZoneName:"short"},full:{hour:"numeric",minute:"numeric",second:"numeric",timeZoneName:"short"}}},e}(),Ge;(function(e){e.FORMAT_ERROR="FORMAT_ERROR",e.UNSUPPORTED_FORMATTER="UNSUPPORTED_FORMATTER",e.INVALID_CONFIG="INVALID_CONFIG",e.MISSING_DATA="MISSING_DATA",e.MISSING_TRANSLATION="MISSING_TRANSLATION"})(Ge||(Ge={}));var it=function(e){St(t,e);function t(n,r,o){var i=this,a=o?o instanceof Error?o:new Error(String(o)):void 0;return i=e.call(this,"[@formatjs/intl Error ".concat(n,"] ").concat(r,` +`).concat(a?` +`.concat(a.message,` +`).concat(a.stack):""))||this,i.code=n,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(i,t),i}return t}(Error),Z2=function(e){St(t,e);function t(n,r){return e.call(this,Ge.UNSUPPORTED_FORMATTER,n,r)||this}return t}(it),Y2=function(e){St(t,e);function t(n,r){return e.call(this,Ge.INVALID_CONFIG,n,r)||this}return t}(it),Gh=function(e){St(t,e);function t(n,r){return e.call(this,Ge.MISSING_DATA,n,r)||this}return t}(it),Tu=function(e){St(t,e);function t(n,r,o){return e.call(this,Ge.FORMAT_ERROR,"".concat(n,` +Locale: `).concat(r,` +`),o)||this}return t}(it),ku=function(e){St(t,e);function t(n,r,o,i){var a=e.call(this,"".concat(n,` +MessageID: `).concat(o==null?void 0:o.id,` +Default Message: `).concat(o==null?void 0:o.defaultMessage,` +Description: `).concat(o==null?void 0:o.description,` +`),r,i)||this;return a.descriptor=o,a}return t}(Tu),K2=function(e){St(t,e);function t(n,r){var o=e.call(this,Ge.MISSING_TRANSLATION,'Missing message: "'.concat(n.id,'" for locale "').concat(r,'", using ').concat(n.defaultMessage?"default message (".concat(typeof n.defaultMessage=="string"?n.defaultMessage:n.defaultMessage.map(function(i){var a;return(a=i.value)!==null&&a!==void 0?a:JSON.stringify(i)}).join(),")"):"id"," as fallback."))||this;return o.descriptor=n,o}return t}(it);function jn(e,t,n){return n===void 0&&(n={}),t.reduce(function(r,o){return o in e?r[o]=e[o]:o in n&&(r[o]=n[o]),r},{})}var J2=function(e){},q2=function(e){},Wh={formats:{},messages:{},timeZone:void 0,defaultLocale:"en",defaultFormats:{},fallbackOnEmptyString:!0,onError:J2,onWarn:q2};function Xh(){return{dateTime:{},number:{},message:{},relativeTime:{},pluralRules:{},list:{},displayNames:{}}}function Vn(e){return{create:function(){return{get:function(t){return e[t]},set:function(t,n){e[t]=n}}}}}function ey(e){e===void 0&&(e=Xh());var t=Intl.RelativeTimeFormat,n=Intl.ListFormat,r=Intl.DisplayNames,o=zt(function(){for(var l,s=[],u=0;u needs to exist in the component ancestry.")}var t0=O(O({},Wh),{textComponent:B.exports.Fragment});function xy(e){return function(t){return e(B.exports.Children.toArray(t))}}function Cy(e,t){if(e===t)return!0;if(!e||!t)return!1;var n=Object.keys(e),r=Object.keys(t),o=n.length;if(r.length!==o)return!1;for(var i=0;i{const t=Pu(),n=Py(t);return x(l0.Provider,{value:n,children:e})},Ay=()=>B.exports.useContext(l0),My=()=>e=>window.entando.router.push(e),s0=e=>{const t=new CustomEvent("tutorial",{detail:{nextStep:e}});window.dispatchEvent(t)},Ny=e=>{var t;return!e||!e.length?"":(t=e==null?void 0:e.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g))==null?void 0:t.map(n=>n.toLowerCase()).join("_")},u0=e=>Object.keys(gh).find(t=>{const n=gh[t];let r=!1;return Array.isArray(n)?r=n.some(o=>e.includes(o)):r=e.includes(n),r})||"",Oy=(e="")=>{const[t,n]=B.exports.useState(e||u0(window.location.pathname));return B.exports.useEffect(()=>{const r=window.entando.router.listen(({pathname:o})=>{n(u0(o))});return()=>{r()}},[]),{activeMenuItem:t,setActiveMenuItem:n}},Ly=_e.menu` + height: 100%; + background-color: ${G.backgroundPrimary}; + border-right: 1px solid ${G.neutralGrey}; + bottom: 0; + left: 0; + font-family: Inter, serif; + overflow-x: hidden; + overflow-y: auto; + position: fixed; + top: 50px; + width: 215px; + z-index: 1030; +`,Hy=_e.a` + display: inline-block; + font-size: 16px; + font-weight: 400; + line-height: 26px; + margin: 0; + padding: 0; + padding-right: 10px; + text-align: left; + text-decoration: none; + &:hover { + color: ${G.textSecondary}; + font-weight: bold; + } +`,Dy=_e.div` + display: flex; + transform: scale(0.8) +`;function Fy(e){var q;const{config:t,dynamicMenuItems:n,openDefaultSubmenuId:r="",epcHasError:o,hideContentMenuItem:i}=e,{userPermissions:a,systemReport:l,adminConsoleUrl:s,lang:u,advancedSearchOn:c}=((q=window.entando)==null?void 0:q.globals)||{},{activeMenuItem:m,setActiveMenuItem:p}=Oy(r),[g,v]=B.exports.useState(""),[S,C]=B.exports.useState(""),[d,f]=B.exports.useState(!!r),[h,w]=B.exports.useState(!1),E=Ay(),_=My(),A=u||a0,b=r2(n),Y={activeListGroupItemId:m,activeSecondaryMenuItemId:g,activeTertiaryMenuItemId:S,setActiveListGroupItemId:p,setActiveSecondaryMenuItemId:v,setActiveTertiaryMenuItemId:C,secondaryMenuOpen:d,setSecondaryMenuOpen:f,tertiaryMenuOpen:h,setTertiaryMenuOpen:w},H=At([fu,Sa],a),Ee=At([fu,Sa,eh],a),we=Ee,Re=At(No,a),Je=At([No,Sa],a),Ae=At([No,qp],a),Nt=At(No,a),De=At([fu,eh,qp,Sa],a),R=At(No,a),L=R||At(Jg,a),D=At([Yg,Zg,Kg],a);return x(Mo.Provider,{value:Y,children:x(Ly,{"data-id":wg,children:ye(pg,{children:[x(kn,{id:"dashboard",dataId:"dashboard",label:E.dashboard,renderIcon:T=>x(Mg,xt({},T)),onClick:()=>_(nh)}),At(Qg,a)&&ye(kn,{id:"pages",dataId:"pages",label:E.pages,className:"app-tour-step-3",renderIcon:T=>x(Ag,xt({},T)),onClick:()=>s0(4),children:[x(le,{id:"pages-management",dataId:"pages-management",label:E.management,className:"app-tour-step-4",onClick:()=>{s0(5),_(rh)}}),x(le,{id:"pages-designer",dataId:"pages-designer",label:E.designer,onClick:()=>_(qg(i2,{pageCode:e2}))}),R&&ye(wa,{children:[x(le,{id:"pages-templates",dataId:"pages-templates",label:E.templates,onClick:()=>_(oh)}),x(le,{id:"pages-settings",dataId:"pages-settings",label:E.settings,onClick:()=>_(o2)})]})]}),R&&ye(kn,{id:"components",dataId:"components",label:E.components,renderIcon:T=>x(Ng,xt({},T)),children:[x(le,{id:"components-widgets",dataId:"components-widgets",label:E.mfeAndWidgets,onClick:()=>_(ih)}),x(le,{id:"components-fragments",dataId:"components-fragments",label:E.uxFragments,onClick:()=>_(ah)})]}),De&&!i&&ye(kn,{id:"content",dataId:"content",label:E.content,renderIcon:T=>x(Og,xt({},T)),children:[H&&x(le,{id:"content-management",dataId:"content-management",label:E.management,href:tn(s,"do/jacms/Content/list.action")}),Ee&&x(le,{id:"content-assets",dataId:"content-assets",label:E.assets,href:tn(s,"do/jacms/Resource/list.action?resourceTypeCode=Image")}),Je&&x(le,{id:"content-templates",dataId:"content-templates",label:E.templates,href:tn(s,"do/jacms/ContentModel/list.action")}),Ae&&x(le,{id:"content-categories",dataId:"content-categories",label:E.categories,href:tn(s,"do/Category/viewTree.action")}),we&&x(le,{id:"content-versioning",dataId:"content-versioning",label:E.versioning,href:tn(s,"do/jpversioning/Content/Versioning/list.action")}),H&&(l==null?void 0:l.contentSchedulerPluginInstalled)&&x(le,{id:"content-scheduler",dataId:"content-scheduler",label:E.contentScheduler,href:tn(s,"do/jpcontentscheduler/config/viewItem.action")}),Re&&x(le,{id:"content-types",dataId:"content-types",label:E.types,href:tn(s,"do/Entity/initViewEntityTypes.action?entityManagerName=jacmsContentManager")}),Nt&&x(le,{id:"content-settings",dataId:"content-settings",label:E.settings,href:tn(s,"do/jacms/Content/Admin/openIndexProspect.action")}),c&&x(le,{id:"content-solr-configuration",dataId:"solr-configuration",label:E.solrConfig,href:tn(s,"do/jpsolr/config")})]}),D&&ye(kn,{id:"users",dataId:"users",label:E.users,renderIcon:T=>x(Lg,xt({},T)),children:[x(le,{id:"users-management",dataId:"users-management",label:E.management,onClick:()=>_(lh)}),R&&ye(wa,{children:[x(le,{id:"users-roles",dataId:"users-roles",label:E.roles,onClick:()=>_(fh)}),x(le,{id:"users-groups",dataId:"users-groups",label:E.groups,onClick:()=>_(uh)}),x(le,{id:"users-profile-types",dataId:"users-profile-types",label:E.profileTypes,onClick:()=>_(sh)}),x(le,{id:"users-restrictions",dataId:"users-restrictions",label:E.restrictions,onClick:()=>_(a2)})]})]}),L&&x(kn,{id:"repository",dataId:"repository",label:E.repository,renderIcon:T=>x(Hg,xt({},T)),onClick:()=>_(hh)}),x(kn,{id:"epc",dataId:"epc",label:E.EPCS,hasError:o,errorTooltipLabel:E.epcHasError,renderIcon:T=>x(Dy,{children:x(Dg,xt({},T))}),children:b!=null&&b.length?b.map(T=>x(le,{id:T.parent,label:T.parent,dataId:T.parent,children:T.children.map(I=>{var P;const M=(P=Object.values(I.label))==null?void 0:P[0],F=I.label.en||M||"",y=`${I.pbcName}_${I.bundleCode}_${Ny(F)}`,j=I.hrefTarget===th;return x(Xg,{id:y,dataId:I.mfeName?I.mfeName:j?"external":void 0,label:I.label[A]||M||I.mfeName,href:j?I.url:void 0,onClick:()=>!j&&I.url&&_(I.url),target:I.hrefTarget,rel:I.rel},y)})},T.parent)):x(Hy,{href:"https://hub.entando.com/",target:"_blank",rel:"noopener noreferrer",children:E.epcPlaceholder})}),R&&ye(kn,{id:"admin",dataId:"admin",label:E.administration,renderIcon:T=>x(Fg,xt({},T)),fixBottom:!0,children:[x(le,{id:"admin-database",dataId:"admin-database",label:E.database,onClick:()=>_(dh)}),x(le,{id:"admin-file-browser",dataId:"admin-file-browser",label:E.fileBrowser,onClick:()=>_(ph)}),x(le,{id:"admin-languages-and-labels",dataId:"admin-languages-and-labels",label:E.languageAndLabels,onClick:()=>_(ch)}),x(le,{id:"admin-email-configuration",dataId:"admin-email-configuration",label:E.emailConfiguration,onClick:()=>_(mh)}),x(le,{id:"admin-reload-configuration",dataId:"admin-reload-configuration",label:E.reloadConfiguration,onClick:()=>_(vh)})]})]})})})}var By={"app.dashboard":"Dashboard","app.pages":"Pages","app.components":"Components","app.content":"Content","app.users":"Users","app.repository":"Hub","app.epcs":"EPCs","app.management":"Management","app.designer":"Designer","app.templates":"Templates","app.settings":"Settings","app.mfeAndWidgets":"MFE & Widgets","app.uxFragments":"UX Fragments","app.assets":"Assets","app.categories":"Categories","app.versioning":"Versioning","app.contentScheduler":"Content Scheduler","app.types":"Types","app.roles":"Roles","app.groups":"Groups","app.profileTypes":"Profile Types","app.restrictions":"Restrictions","app.administration":"Administration","app.database":"Database","app.fileBrowser":"File browser","app.languageAndLabels":"Language & Labels","app.emailConfiguration":"Email Configuration","app.reloadConfiguration":"Reload Configuration","app.epcPlaceholder":"Install your first Entando Platform Capability","app.epcHasError":"EPCs not available, something went wrong during the installation of one EPC","app.solrConfig":"SOLR configuration"},Uy={"app.dashboard":"Dashboard","app.pages":"Pagine","app.components":"Componenti","app.content":"Contenuti","app.users":"Utenti","app.repository":"Hub","app.epcs":"EPCs","app.management":"Gestione","app.designer":"Designer","app.templates":"Modelli","app.settings":"Impostazioni","app.mfeAndWidgets":"MFE e widget","app.uxFragments":"Frammenti UX","app.assets":"Risorse","app.categories":"Categorie","app.versioning":"Versionamento","app.contentScheduler":"Utilit\xE0 di pianificazione dei contenuti","app.types":"Tipi","app.roles":"Ruoli","app.groups":"Gruppi","app.profileTypes":"Tipi di profilo","app.restrictions":"Restrizioni","app.administration":"Amministrazione","app.database":"Database","app.fileBrowser":"Browser di file","app.languageAndLabels":"Lingua ed etichette","app.emailConfiguration":"Configurazione e-mail","app.reloadConfiguration":"Ricarica configurazione","app.epcPlaceholder":"Installa la tua prima Entando Platform Capability","app.epcHasError":"EPC non disponibili, si \xE8 verificato un problema con l'installazione di un EPC","app.solrConfig":"SOLR configurazione"},$y={"app.dashboard":"Painel","app.pages":"P\xE1ginas","app.components":"Componentes","app.content":"Conte\xFAdo","app.users":"Usu\xE1rios","app.repository":"Hub","app.epcs":"EPCs","app.management":"Gerenciamento","app.designer":"Designer","app.templates":"Modelos","app.settings":"Configura\xE7\xF5es","app.mfeAndWidgets":"MFE e Widgets","app.uxFragments":"Fragmentos de UX","app.assets":"Ativos","app.categories":"Categorias","app.versioning":"Versionamento","app.contentScheduler":"Agendador de conte\xFAdo","app.types":"Tipos","app.roles":"Fun\xE7\xF5es","app.groups":"Grupos","app.profileTypes":"Tipos de perfil","app.restrictions":"Restri\xE7\xF5es","app.administration":"Administra\xE7\xE3o","app.database":"Banco de dados","app.fileBrowser":"Navegador de arquivos","app.languageAndLabels":"Idioma e R\xF3tulos","app.emailConfiguration":"Configura\xE7\xE3o de e-mail","app.reloadConfiguration":"Recarregar configura\xE7\xE3o","app.epcPlaceholder":"Instale sua primeira Entando Platform Capability","app.epcHasError":"EPC n\xE3o dispon\xEDvel, algo deu errado durante a instala\xE7\xE3o","app.solrConfig":"SOLR configura\xE7\xE3o"};const zy=dg` +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} + +* { + box-sizing: border-box; +} + +:host { + --balloon-border-radius: 2px; + --balloon-color: rgba(16, 16, 16, 0.95); + --balloon-text-color: #fff; + --balloon-font-size: 12px; + --balloon-move: 4px; +} + +button[aria-label][data-balloon-pos] { + overflow: visible; } + +[aria-label][data-balloon-pos] { + position: relative; + cursor: pointer; } + [aria-label][data-balloon-pos]:after { + opacity: 0; + pointer-events: none; + transition: all 0.18s ease-out 0.18s; + text-indent: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; + font-weight: normal; + font-style: normal; + text-shadow: none; + font-size: var(--balloon-font-size); + background: var(--balloon-color); + border-radius: 2px; + color: var(--balloon-text-color); + border-radius: var(--balloon-border-radius); + content: attr(aria-label); + padding: .5em 1em; + position: absolute; + white-space: nowrap; + z-index: 10; } + [aria-label][data-balloon-pos]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-top-color: var(--balloon-color); + opacity: 0; + pointer-events: none; + transition: all 0.18s ease-out 0.18s; + content: ""; + position: absolute; + z-index: 10; } + [aria-label][data-balloon-pos]:hover:before, [aria-label][data-balloon-pos]:hover:after, [aria-label][data-balloon-pos][data-balloon-visible]:before, [aria-label][data-balloon-pos][data-balloon-visible]:after, [aria-label][data-balloon-pos]:not([data-balloon-nofocus]):focus:before, [aria-label][data-balloon-pos]:not([data-balloon-nofocus]):focus:after { + opacity: 1; + pointer-events: none; } + [aria-label][data-balloon-pos].font-awesome:after { + font-family: FontAwesome, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } + [aria-label][data-balloon-pos][data-balloon-break]:after { + white-space: pre; } + [aria-label][data-balloon-pos][data-balloon-break][data-balloon-length]:after { + white-space: pre-line; + word-break: break-word; } + [aria-label][data-balloon-pos][data-balloon-blunt]:before, [aria-label][data-balloon-pos][data-balloon-blunt]:after { + transition: none; } + [aria-label][data-balloon-pos][data-balloon-pos="up"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="up"][data-balloon-visible]:after, [aria-label][data-balloon-pos][data-balloon-pos="down"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="down"][data-balloon-visible]:after { + transform: translate(-50%, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="up"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="up"][data-balloon-visible]:before, [aria-label][data-balloon-pos][data-balloon-pos="down"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="down"][data-balloon-visible]:before { + transform: translate(-50%, 0); } + [aria-label][data-balloon-pos][data-balloon-pos*="-left"]:after { + left: 0; } + [aria-label][data-balloon-pos][data-balloon-pos*="-left"]:before { + left: 5px; } + [aria-label][data-balloon-pos][data-balloon-pos*="-right"]:after { + right: 0; } + [aria-label][data-balloon-pos][data-balloon-pos*="-right"]:before { + right: 5px; } + [aria-label][data-balloon-pos][data-balloon-pos*="-left"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos*="-left"][data-balloon-visible]:after, [aria-label][data-balloon-pos][data-balloon-pos*="-right"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos*="-right"][data-balloon-visible]:after { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos*="-left"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos*="-left"][data-balloon-visible]:before, [aria-label][data-balloon-pos][data-balloon-pos*="-right"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos*="-right"][data-balloon-visible]:before { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos^="up"]:before, [aria-label][data-balloon-pos][data-balloon-pos^="up"]:after { + bottom: 100%; + transform-origin: top; + transform: translate(0, var(--balloon-move)); } + [aria-label][data-balloon-pos][data-balloon-pos^="up"]:after { + margin-bottom: 10px; } + [aria-label][data-balloon-pos][data-balloon-pos="up"]:before, [aria-label][data-balloon-pos][data-balloon-pos="up"]:after { + left: 50%; + transform: translate(-50%, var(--balloon-move)); } + [aria-label][data-balloon-pos][data-balloon-pos^="down"]:before, [aria-label][data-balloon-pos][data-balloon-pos^="down"]:after { + top: 100%; + transform: translate(0, calc(var(--balloon-move) * -1)); } + [aria-label][data-balloon-pos][data-balloon-pos^="down"]:after { + margin-top: 10px; } + [aria-label][data-balloon-pos][data-balloon-pos^="down"]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-bottom-color: var(--balloon-color); } + [aria-label][data-balloon-pos][data-balloon-pos="down"]:after, [aria-label][data-balloon-pos][data-balloon-pos="down"]:before { + left: 50%; + transform: translate(-50%, calc(var(--balloon-move) * -1)); } + [aria-label][data-balloon-pos][data-balloon-pos="left"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="left"][data-balloon-visible]:after, [aria-label][data-balloon-pos][data-balloon-pos="right"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="right"][data-balloon-visible]:after { + transform: translate(0, -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="left"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="left"][data-balloon-visible]:before, [aria-label][data-balloon-pos][data-balloon-pos="right"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="right"][data-balloon-visible]:before { + transform: translate(0, -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="left"]:after, [aria-label][data-balloon-pos][data-balloon-pos="left"]:before { + right: 100%; + top: 50%; + transform: translate(var(--balloon-move), -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="left"]:after { + margin-right: 10px; } + [aria-label][data-balloon-pos][data-balloon-pos="left"]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-left-color: var(--balloon-color); } + [aria-label][data-balloon-pos][data-balloon-pos="right"]:after, [aria-label][data-balloon-pos][data-balloon-pos="right"]:before { + left: 100%; + top: 50%; + transform: translate(calc(var(--balloon-move) * -1), -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="right"]:after { + margin-left: 10px; } + [aria-label][data-balloon-pos][data-balloon-pos="right"]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-right-color: var(--balloon-color); } + [aria-label][data-balloon-pos][data-balloon-length]:after { + white-space: normal; } + [aria-label][data-balloon-pos][data-balloon-length="small"]:after { + width: 80px; } + [aria-label][data-balloon-pos][data-balloon-length="medium"]:after { + width: 150px; } + [aria-label][data-balloon-pos][data-balloon-length="large"]:after { + width: 260px; } + [aria-label][data-balloon-pos][data-balloon-length="xlarge"]:after { + width: 380px; } + @media screen and (max-width: 768px) { + [aria-label][data-balloon-pos][data-balloon-length="xlarge"]:after { + width: 90vw; } } + [aria-label][data-balloon-pos][data-balloon-length="fit"]:after { + width: 100%; } + +`;var Nu={exports:{}},c0=function(t,n){return function(){for(var o=new Array(arguments.length),i=0;i0;)i=r[o],a[i]||(t[i]=e[i],a[i]=!0);e=Object.getPrototypeOf(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t}function l3(e,t,n){e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;var r=e.indexOf(t,n);return r!==-1&&r===n}function s3(e){if(!e)return null;var t=e.length;if(_a(t))return null;for(var n=new Array(t);t-- >0;)n[t]=e[t];return n}var u3=function(e){return function(t){return e&&t instanceof e}}(typeof Uint8Array!="undefined"&&Object.getPrototypeOf(Uint8Array)),He={isArray:Hu,isArrayBuffer:f0,isBuffer:Vy,isFormData:qy,isArrayBufferView:Gy,isString:Wy,isNumber:Xy,isObject:d0,isPlainObject:Ra,isUndefined:_a,isDate:Qy,isFile:Zy,isBlob:Yy,isFunction:Du,isStream:Jy,isURLSearchParams:e3,isStandardBrowserEnv:n3,forEach:Fu,merge:Bu,extend:r3,trim:t3,stripBOM:o3,inherits:i3,toFlatObject:a3,kindOf:Lu,kindOfTest:Gn,endsWith:l3,toArray:s3,isTypedArray:u3,isFileList:Ky},Cr=He;function p0(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var h0=function(t,n,r){if(!n)return t;var o;if(r)o=r(n);else if(Cr.isURLSearchParams(n))o=n.toString();else{var i=[];Cr.forEach(n,function(s,u){s===null||typeof s=="undefined"||(Cr.isArray(s)?u=u+"[]":s=[s],Cr.forEach(s,function(m){Cr.isDate(m)?m=m.toISOString():Cr.isObject(m)&&(m=JSON.stringify(m)),i.push(p0(u)+"="+p0(m))}))}),o=i.join("&")}if(o){var a=t.indexOf("#");a!==-1&&(t=t.slice(0,a)),t+=(t.indexOf("?")===-1?"?":"&")+o}return t},c3=He;function Ia(){this.handlers=[]}Ia.prototype.use=function(t,n,r){return this.handlers.push({fulfilled:t,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1},Ia.prototype.eject=function(t){this.handlers[t]&&(this.handlers[t]=null)},Ia.prototype.forEach=function(t){c3.forEach(this.handlers,function(r){r!==null&&t(r)})};var f3=Ia,d3=He,p3=function(t,n){d3.forEach(t,function(o,i){i!==n&&i.toUpperCase()===n.toUpperCase()&&(t[n]=o,delete t[i])})},m0=He;function Tr(e,t,n,r,o){Error.call(this),this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),o&&(this.response=o)}m0.inherits(Tr,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code,status:this.response&&this.response.status?this.response.status:null}}});var v0=Tr.prototype,g0={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED"].forEach(function(e){g0[e]={value:e}}),Object.defineProperties(Tr,g0),Object.defineProperty(v0,"isAxiosError",{value:!0}),Tr.from=function(e,t,n,r,o,i){var a=Object.create(v0);return m0.toFlatObject(e,a,function(s){return s!==Error.prototype}),Tr.call(a,e.message,t,n,r,o),a.name=e.name,i&&Object.assign(a,i),a};var kr=Tr,y0={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},Mt=He;function h3(e,t){t=t||new FormData;var n=[];function r(i){return i===null?"":Mt.isDate(i)?i.toISOString():Mt.isArrayBuffer(i)||Mt.isTypedArray(i)?typeof Blob=="function"?new Blob([i]):Buffer.from(i):i}function o(i,a){if(Mt.isPlainObject(i)||Mt.isArray(i)){if(n.indexOf(i)!==-1)throw Error("Circular reference detected in "+a);n.push(i),Mt.forEach(i,function(s,u){if(!Mt.isUndefined(s)){var c=a?a+"."+u:u,m;if(s&&!a&&typeof s=="object"){if(Mt.endsWith(u,"{}"))s=JSON.stringify(s);else if(Mt.endsWith(u,"[]")&&(m=Mt.toArray(s))){m.forEach(function(p){!Mt.isUndefined(p)&&t.append(c,r(p))});return}}o(s,c)}}),n.pop()}else t.append(a,r(i))}return o(e),t}var E0=h3,Uu=kr,m3=function(t,n,r){var o=r.config.validateStatus;!r.status||!o||o(r.status)?t(r):n(new Uu("Request failed with status code "+r.status,[Uu.ERR_BAD_REQUEST,Uu.ERR_BAD_RESPONSE][Math.floor(r.status/100)-4],r.config,r.request,r))},Pa=He,v3=Pa.isStandardBrowserEnv()?function(){return{write:function(n,r,o,i,a,l){var s=[];s.push(n+"="+encodeURIComponent(r)),Pa.isNumber(o)&&s.push("expires="+new Date(o).toGMTString()),Pa.isString(i)&&s.push("path="+i),Pa.isString(a)&&s.push("domain="+a),l===!0&&s.push("secure"),document.cookie=s.join("; ")},read:function(n){var r=document.cookie.match(new RegExp("(^|;\\s*)("+n+")=([^;]*)"));return r?decodeURIComponent(r[3]):null},remove:function(n){this.write(n,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}(),g3=function(t){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)},y3=function(t,n){return n?t.replace(/\/+$/,"")+"/"+n.replace(/^\/+/,""):t},E3=g3,w3=y3,w0=function(t,n){return t&&!E3(n)?w3(t,n):n},$u=He,S3=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"],x3=function(t){var n={},r,o,i;return t&&$u.forEach(t.split(` +`),function(l){if(i=l.indexOf(":"),r=$u.trim(l.substr(0,i)).toLowerCase(),o=$u.trim(l.substr(i+1)),r){if(n[r]&&S3.indexOf(r)>=0)return;r==="set-cookie"?n[r]=(n[r]?n[r]:[]).concat([o]):n[r]=n[r]?n[r]+", "+o:o}}),n},S0=He,C3=S0.isStandardBrowserEnv()?function(){var t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a"),r;function o(i){var a=i;return t&&(n.setAttribute("href",a),a=n.href),n.setAttribute("href",a),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:n.pathname.charAt(0)==="/"?n.pathname:"/"+n.pathname}}return r=o(window.location.href),function(a){var l=S0.isString(a)?o(a):a;return l.protocol===r.protocol&&l.host===r.host}}():function(){return function(){return!0}}(),zu=kr,T3=He;function x0(e){zu.call(this,e==null?"canceled":e,zu.ERR_CANCELED),this.name="CanceledError"}T3.inherits(x0,zu,{__CANCEL__:!0});var ba=x0,k3=function(t){var n=/^([-+\w]{1,25})(:?\/\/|:)/.exec(t);return n&&n[1]||""},Lo=He,_3=m3,R3=v3,I3=h0,P3=w0,b3=x3,A3=C3,M3=y0,nn=kr,N3=ba,O3=k3,C0=function(t){return new Promise(function(r,o){var i=t.data,a=t.headers,l=t.responseType,s;function u(){t.cancelToken&&t.cancelToken.unsubscribe(s),t.signal&&t.signal.removeEventListener("abort",s)}Lo.isFormData(i)&&Lo.isStandardBrowserEnv()&&delete a["Content-Type"];var c=new XMLHttpRequest;if(t.auth){var m=t.auth.username||"",p=t.auth.password?unescape(encodeURIComponent(t.auth.password)):"";a.Authorization="Basic "+btoa(m+":"+p)}var g=P3(t.baseURL,t.url);c.open(t.method.toUpperCase(),I3(g,t.params,t.paramsSerializer),!0),c.timeout=t.timeout;function v(){if(!!c){var d="getAllResponseHeaders"in c?b3(c.getAllResponseHeaders()):null,f=!l||l==="text"||l==="json"?c.responseText:c.response,h={data:f,status:c.status,statusText:c.statusText,headers:d,config:t,request:c};_3(function(E){r(E),u()},function(E){o(E),u()},h),c=null}}if("onloadend"in c?c.onloadend=v:c.onreadystatechange=function(){!c||c.readyState!==4||c.status===0&&!(c.responseURL&&c.responseURL.indexOf("file:")===0)||setTimeout(v)},c.onabort=function(){!c||(o(new nn("Request aborted",nn.ECONNABORTED,t,c)),c=null)},c.onerror=function(){o(new nn("Network Error",nn.ERR_NETWORK,t,c,c)),c=null},c.ontimeout=function(){var f=t.timeout?"timeout of "+t.timeout+"ms exceeded":"timeout exceeded",h=t.transitional||M3;t.timeoutErrorMessage&&(f=t.timeoutErrorMessage),o(new nn(f,h.clarifyTimeoutError?nn.ETIMEDOUT:nn.ECONNABORTED,t,c)),c=null},Lo.isStandardBrowserEnv()){var S=(t.withCredentials||A3(g))&&t.xsrfCookieName?R3.read(t.xsrfCookieName):void 0;S&&(a[t.xsrfHeaderName]=S)}"setRequestHeader"in c&&Lo.forEach(a,function(f,h){typeof i=="undefined"&&h.toLowerCase()==="content-type"?delete a[h]:c.setRequestHeader(h,f)}),Lo.isUndefined(t.withCredentials)||(c.withCredentials=!!t.withCredentials),l&&l!=="json"&&(c.responseType=t.responseType),typeof t.onDownloadProgress=="function"&&c.addEventListener("progress",t.onDownloadProgress),typeof t.onUploadProgress=="function"&&c.upload&&c.upload.addEventListener("progress",t.onUploadProgress),(t.cancelToken||t.signal)&&(s=function(d){!c||(o(!d||d&&d.type?new N3:d),c.abort(),c=null)},t.cancelToken&&t.cancelToken.subscribe(s),t.signal&&(t.signal.aborted?s():t.signal.addEventListener("abort",s))),i||(i=null);var C=O3(g);if(C&&["http","https","file"].indexOf(C)===-1){o(new nn("Unsupported protocol "+C+":",nn.ERR_BAD_REQUEST,t));return}c.send(i)})},L3=null,be=He,T0=p3,k0=kr,H3=y0,D3=E0,F3={"Content-Type":"application/x-www-form-urlencoded"};function _0(e,t){!be.isUndefined(e)&&be.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function B3(){var e;return(typeof XMLHttpRequest!="undefined"||typeof process!="undefined"&&Object.prototype.toString.call(process)==="[object process]")&&(e=C0),e}function U3(e,t,n){if(be.isString(e))try{return(t||JSON.parse)(e),be.trim(e)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(e)}var Aa={transitional:H3,adapter:B3(),transformRequest:[function(t,n){if(T0(n,"Accept"),T0(n,"Content-Type"),be.isFormData(t)||be.isArrayBuffer(t)||be.isBuffer(t)||be.isStream(t)||be.isFile(t)||be.isBlob(t))return t;if(be.isArrayBufferView(t))return t.buffer;if(be.isURLSearchParams(t))return _0(n,"application/x-www-form-urlencoded;charset=utf-8"),t.toString();var r=be.isObject(t),o=n&&n["Content-Type"],i;if((i=be.isFileList(t))||r&&o==="multipart/form-data"){var a=this.env&&this.env.FormData;return D3(i?{"files[]":t}:t,a&&new a)}else if(r||o==="application/json")return _0(n,"application/json"),U3(t);return t}],transformResponse:[function(t){var n=this.transitional||Aa.transitional,r=n&&n.silentJSONParsing,o=n&&n.forcedJSONParsing,i=!r&&this.responseType==="json";if(i||o&&be.isString(t)&&t.length)try{return JSON.parse(t)}catch(a){if(i)throw a.name==="SyntaxError"?k0.from(a,k0.ERR_BAD_RESPONSE,this,null,this.response):a}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:L3},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*"}}};be.forEach(["delete","get","head"],function(t){Aa.headers[t]={}}),be.forEach(["post","put","patch"],function(t){Aa.headers[t]=be.merge(F3)});var ju=Aa,$3=He,z3=ju,j3=function(t,n,r){var o=this||z3;return $3.forEach(r,function(a){t=a.call(o,t,n)}),t},R0=function(t){return!!(t&&t.__CANCEL__)},I0=He,Vu=j3,V3=R0,G3=ju,W3=ba;function Gu(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new W3}var X3=function(t){Gu(t),t.headers=t.headers||{},t.data=Vu.call(t,t.data,t.headers,t.transformRequest),t.headers=I0.merge(t.headers.common||{},t.headers[t.method]||{},t.headers),I0.forEach(["delete","get","head","post","put","patch","common"],function(o){delete t.headers[o]});var n=t.adapter||G3.adapter;return n(t).then(function(o){return Gu(t),o.data=Vu.call(t,o.data,o.headers,t.transformResponse),o},function(o){return V3(o)||(Gu(t),o&&o.response&&(o.response.data=Vu.call(t,o.response.data,o.response.headers,t.transformResponse))),Promise.reject(o)})},pt=He,P0=function(t,n){n=n||{};var r={};function o(c,m){return pt.isPlainObject(c)&&pt.isPlainObject(m)?pt.merge(c,m):pt.isPlainObject(m)?pt.merge({},m):pt.isArray(m)?m.slice():m}function i(c){if(pt.isUndefined(n[c])){if(!pt.isUndefined(t[c]))return o(void 0,t[c])}else return o(t[c],n[c])}function a(c){if(!pt.isUndefined(n[c]))return o(void 0,n[c])}function l(c){if(pt.isUndefined(n[c])){if(!pt.isUndefined(t[c]))return o(void 0,t[c])}else return o(void 0,n[c])}function s(c){if(c in n)return o(t[c],n[c]);if(c in t)return o(void 0,t[c])}var u={url:a,method:a,data:a,baseURL:l,transformRequest:l,transformResponse:l,paramsSerializer:l,timeout:l,timeoutMessage:l,withCredentials:l,adapter:l,responseType:l,xsrfCookieName:l,xsrfHeaderName:l,onUploadProgress:l,onDownloadProgress:l,decompress:l,maxContentLength:l,maxBodyLength:l,beforeRedirect:l,transport:l,httpAgent:l,httpsAgent:l,cancelToken:l,socketPath:l,responseEncoding:l,validateStatus:s};return pt.forEach(Object.keys(t).concat(Object.keys(n)),function(m){var p=u[m]||i,g=p(m);pt.isUndefined(g)&&p!==s||(r[m]=g)}),r},b0={version:"0.27.2"},Q3=b0.version,Rn=kr,Wu={};["object","boolean","number","function","string","symbol"].forEach(function(e,t){Wu[e]=function(r){return typeof r===e||"a"+(t<1?"n ":" ")+e}});var A0={};Wu.transitional=function(t,n,r){function o(i,a){return"[Axios v"+Q3+"] Transitional option '"+i+"'"+a+(r?". "+r:"")}return function(i,a,l){if(t===!1)throw new Rn(o(a," has been removed"+(n?" in "+n:"")),Rn.ERR_DEPRECATED);return n&&!A0[a]&&(A0[a]=!0,console.warn(o(a," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(i,a,l):!0}};function Z3(e,t,n){if(typeof e!="object")throw new Rn("options must be an object",Rn.ERR_BAD_OPTION_VALUE);for(var r=Object.keys(e),o=r.length;o-- >0;){var i=r[o],a=t[i];if(a){var l=e[i],s=l===void 0||a(l,i,e);if(s!==!0)throw new Rn("option "+i+" must be "+s,Rn.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new Rn("Unknown option "+i,Rn.ERR_BAD_OPTION)}}var Y3={assertOptions:Z3,validators:Wu},M0=He,K3=h0,N0=f3,O0=X3,Ma=P0,J3=w0,L0=Y3,_r=L0.validators;function Rr(e){this.defaults=e,this.interceptors={request:new N0,response:new N0}}Rr.prototype.request=function(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=Ma(this.defaults,n),n.method?n.method=n.method.toLowerCase():this.defaults.method?n.method=this.defaults.method.toLowerCase():n.method="get";var r=n.transitional;r!==void 0&&L0.assertOptions(r,{silentJSONParsing:_r.transitional(_r.boolean),forcedJSONParsing:_r.transitional(_r.boolean),clarifyTimeoutError:_r.transitional(_r.boolean)},!1);var o=[],i=!0;this.interceptors.request.forEach(function(g){typeof g.runWhen=="function"&&g.runWhen(n)===!1||(i=i&&g.synchronous,o.unshift(g.fulfilled,g.rejected))});var a=[];this.interceptors.response.forEach(function(g){a.push(g.fulfilled,g.rejected)});var l;if(!i){var s=[O0,void 0];for(Array.prototype.unshift.apply(s,o),s=s.concat(a),l=Promise.resolve(n);s.length;)l=l.then(s.shift(),s.shift());return l}for(var u=n;o.length;){var c=o.shift(),m=o.shift();try{u=c(u)}catch(p){m(p);break}}try{l=O0(u)}catch(p){return Promise.reject(p)}for(;a.length;)l=l.then(a.shift(),a.shift());return l},Rr.prototype.getUri=function(t){t=Ma(this.defaults,t);var n=J3(t.baseURL,t.url);return K3(n,t.params,t.paramsSerializer)},M0.forEach(["delete","get","head","options"],function(t){Rr.prototype[t]=function(n,r){return this.request(Ma(r||{},{method:t,url:n,data:(r||{}).data}))}}),M0.forEach(["post","put","patch"],function(t){function n(r){return function(i,a,l){return this.request(Ma(l||{},{method:t,headers:r?{"Content-Type":"multipart/form-data"}:{},url:i,data:a}))}}Rr.prototype[t]=n(),Rr.prototype[t+"Form"]=n(!0)});var q3=Rr,e6=ba;function Ir(e){if(typeof e!="function")throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(o){t=o});var n=this;this.promise.then(function(r){if(!!n._listeners){var o,i=n._listeners.length;for(o=0;owindow.entando.keycloak.token;function c6(e,t){var r,o;const{url:n}=(o=(r=t==null?void 0:t.systemParams)==null?void 0:r.api[e])!=null?o:{};return n.endsWith("/")?n.substring(0,n.length-1):n}async function f6(e){return s6.get(`${c6("navigation",e)}/api/nav`,{headers:{Authorization:`Bearer ${u6()}`}})}const d6={en:By,it:Uy,pt:$y};function p6(e){var v;const{config:t}=e,[n,r]=B.exports.useState(!0),[o,i]=B.exports.useState([]),[a,l]=B.exports.useState(!1),[s,u]=B.exports.useState(!1),c=sessionStorage.getItem("menu_open")||"",{lang:m,disableContentMenu:p}=((v=window.entando)==null?void 0:v.globals)||{},g=m||a0;return B.exports.useEffect(()=>{u(p||!1)},[p]),B.exports.useEffect(()=>{const S=C=>{const{disableContentMenu:d}=C.detail;u(d||!1)};return window.addEventListener("user-preferences-updated",S),()=>{window.removeEventListener("user-preferences-updated",S)}},[]),B.exports.useEffect(()=>{t&&(async()=>{try{const{data:d}=await f6(t);!d||!Array.isArray(d.payload)?l(!0):i((d==null?void 0:d.payload)||[])}catch{l(!0)}r(!1)})();const C=()=>{sessionStorage.removeItem("menu_open")};if(c)return window.addEventListener("beforeunload",C),()=>{C(),window.removeEventListener("beforeunload",C)}},[]),x(Iy,{locale:g,defaultLocale:"en",messages:d6[g],children:x(by,{children:n?x("div",{children:"Loading..."}):ye(wa,{children:[x(zy,{}),x(Fy,{config:t,dynamicMenuItems:o,openDefaultSubmenuId:c,epcHasError:a,hideContentMenuItem:s})]})})})}class h6 extends HTMLElement{constructor(){super();Ku(this,Oa);U0(this,"shadow");Ku(this,Ho,{});this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["config"]}attributeChangedCallback(n,r,o){n==="config"&&r!==o&&j0(this,Oa,V0).call(this,o)}connectedCallback(){this.render()}render(){const n=document.createElement("div"),r=document.createElement("div"),o=X.createRoot(n),i="app-builder-menu-main-element-id",a="app-builder-menu-styles-element-id";r.id=a,n.id=i;const l=this.shadow.getElementById(a);l&&this.shadow.removeChild(l);const s=this.shadow.getElementById(i);s&&this.shadow.removeChild(s),o.render(x(tg,{target:r,children:x(p6,{config:$0(this,Ho)})})),this.shadow.appendChild(r),this.shadow.appendChild(n)}}Ho=new WeakMap,Oa=new WeakSet,V0=function(n){z0(this,Ho,JSON.parse(n))},customElements.define("app-builder-menu",h6)}); diff --git a/public/icons/app-builder-icon.svg b/public/icons/app-builder-icon.svg new file mode 100644 index 000000000..bc8484b3f --- /dev/null +++ b/public/icons/app-builder-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/icons/copy.svg b/public/icons/copy.svg new file mode 100644 index 000000000..834252e48 --- /dev/null +++ b/public/icons/copy.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/icons/dashboard.svg b/public/icons/dashboard.svg new file mode 100644 index 000000000..6ed69792f --- /dev/null +++ b/public/icons/dashboard.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/icons/file.svg b/public/icons/file.svg new file mode 100644 index 000000000..659923269 --- /dev/null +++ b/public/icons/file.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/users.svg b/public/icons/users.svg new file mode 100644 index 000000000..e341b762f --- /dev/null +++ b/public/icons/users.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/logo.svg b/public/images/logo.svg new file mode 100644 index 000000000..d20a0c382 --- /dev/null +++ b/public/images/logo.svg @@ -0,0 +1,7 @@ + + + diff --git a/public/index.html b/public/index.html index d06447c23..87365669c 100644 --- a/public/index.html +++ b/public/index.html @@ -10,6 +10,9 @@ --> + + + diff --git a/sass/categories/filter/CategoryTreeFilter.scss b/sass/categories/filter/CategoryTreeFilter.scss index aab08e644..a8507740c 100644 --- a/sass/categories/filter/CategoryTreeFilter.scss +++ b/sass/categories/filter/CategoryTreeFilter.scss @@ -2,7 +2,7 @@ &__title { margin-left: 5px; color: $color-space-grey; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 13px; font-style: normal; font-weight: bold; @@ -28,7 +28,7 @@ &__apply-button { width: 100%; margin-top: 10px; - font-family: "Open Sans"; + font-family: "Inter"; font-weight: 400; @media (min-width: 992px) { diff --git a/sass/common/Button.scss b/sass/common/Button.scss new file mode 100644 index 000000000..fc74dae34 --- /dev/null +++ b/sass/common/Button.scss @@ -0,0 +1,61 @@ +.Button { + display: flex; + align-items: center; + padding-inline: 16px; + font-size: 14px; + font-weight: 500; + border-radius: $spacing-8; + column-gap: 8px; + + &:not(.radius-xxs) { + border-radius: $radius-s; + } + + &.radius-xxs{ + border-radius: $radius-xxs; + } + + .btn:focus { + outline: none; + } + + &.btn-primary, + &.btn-primary:active, + &.btn-primary:focus { + background-color: $color-brand-primary; + border: none; + } + + &.btn-clear { + &-secondary { + background-color: transparent; + border: none; + color: $color-text-secondary; + } + } + + &.btn-link, &.btn-outlined-primary { + color: $color-brand-primary; + font-size: 16px; + font-weight: 500; + + &:hover { + color: $color-brand-primary; + border-color: $color-brand-primary; + background: none; + } + } + + &.btn-outlined-secondary { + &:hover { + background-color: $color-content-09; + } + } + + + &.btn-outlined-secondary, &.btn-outlined-primary { + &:focus, &:focus:hover { + outline: none; + } + } +} \ No newline at end of file diff --git a/sass/common/CardList.scss b/sass/common/CardList.scss new file mode 100644 index 000000000..933dc08d5 --- /dev/null +++ b/sass/common/CardList.scss @@ -0,0 +1,102 @@ +.CardList { + display: grid; + grid-auto-flow: row; + gap: 10px; + padding: 20px; + grid-template-columns: repeat(auto-fill, minmax(250px, 320px)); + grid-auto-rows: 1fr; + justify-content: space-between; + background: rgba(249, 250, 251, 1); +} + +.CardItem { + display: flex; + flex-direction: column; + gap: 6px; + padding: 10px; + background-color: #fff; + border: 1px solid rgba(228, 231, 236, 1); + border-radius: 8px; + position: relative; +} + +.CardItemActions { + position: absolute; + top: 10px; + right: 14px; + + .dropdown-kebab-pf .dropdown-menu.dropdown-menu-right { + width: max-content; + max-width: 320px; + overflow-wrap: anywhere; + padding: 8px; + + .dropdown-menu { + display: flex; + flex-direction: column; + row-gap: 6px; + } + + .FragmentListMenuAction__menu-item-container { + display: flex; + align-items: stretch; + column-gap: 8px; + padding: 4px; + + &:hover{ + background-color: $color-neutral-grey; + } + } + } +} + +.CardItemIconWrapper { + display: flex; + justify-content: center; + align-items: center; + background: rgba(236, 249, 242, 1); + color: $color-green-new; + padding: 6px; + width: fit-content; + border-radius: 50%; + + &>span { + height: 18px; + } +} + +.CardItemLabel { + display: flex; + gap: 10px; + align-items: center +} + +.CardItemTitle { + color: $color-brand-primary; + width: calc(100% - 10px); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 16px; + font-weight: 500; +} + +.CardItemCounter { + display: flex; + justify-content: center; + align-items: center; + padding: 6px; + width: 20px; + height: 20px; + background-color: rgba(242, 244, 247, 1); + border-radius: 50%; + cursor: pointer; +} + +.CardItemSubtitle{ + color: rgba(99, 112, 131, 1); +} + +.CardItemCounter__popover { + font-weight: 600; +} \ No newline at end of file diff --git a/sass/common/CollapsibleSectionTitle.scss b/sass/common/CollapsibleSectionTitle.scss index 99bfd4ce7..b91dee125 100644 --- a/sass/common/CollapsibleSectionTitle.scss +++ b/sass/common/CollapsibleSectionTitle.scss @@ -5,9 +5,9 @@ justify-content: space-between; width: 100%; padding: 10px 10px 10px 30px; - border-top: 1px solid $color-black; + border-top: 1px solid $color-neutral-grey; outline: none; - color: $color-white; + color: $color-content-3; font-size: 14px; font-weight: bold; line-height: inherit; diff --git a/sass/common/DropdownButton.scss b/sass/common/DropdownButton.scss new file mode 100644 index 000000000..37164a61a --- /dev/null +++ b/sass/common/DropdownButton.scss @@ -0,0 +1,20 @@ +.Dropdown-btn { + border-radius: $radius-xxs; + border: 1px solid $color-content-07; + color: $color-text-tertiary; + background-color: transparent; + box-shadow: none; + display: flex; + justify-content: space-between; + align-items: center; + font-size: 14px; + font-weight: 400; + height: 32px; +} + +.dropdown-menu { + border-radius: $radius-xxs; + border: 1px solid $color-content-07; + font-size: 14px; + font-weight: 400; +} \ No newline at end of file diff --git a/sass/common/Icon.scss b/sass/common/Icon.scss new file mode 100644 index 000000000..fede9ffc1 --- /dev/null +++ b/sass/common/Icon.scss @@ -0,0 +1,44 @@ +.Icon { + display: flex; + align-items: center; +} + +.icon__colored-bg, .icon__colored-bg::before { + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background-color: $color-dark-blue; + width: 32px; + height: 32px; +} + +.lucide { + &:not(.primary) { + color: $color-text-tertiary; + } + + &.primary { + color: $color-brand-primary; + } + + &.lucide-component > path { + transform: rotate(45deg); + transform-origin: center; + } + +} + +.active { + .lucide { + color: $color-brand-primary; + } +} + +.icon-flipped-y { + transform: scaleY(-1); +} + +.icon-flipped-x { + transform: scaleX(-1); +} \ No newline at end of file diff --git a/sass/common/Search.scss b/sass/common/Search.scss new file mode 100644 index 000000000..09ae0d66d --- /dev/null +++ b/sass/common/Search.scss @@ -0,0 +1,37 @@ +.Search { + display: flex; + align-items: center; + gap: 4px; + border: 1px solid $color-content-07; + border-radius: $radius-xxs; + + &.reverse { + flex-direction: row-reverse; + justify-content: flex-end; + padding-inline: 10px; + } + + &:focus-within { + outline: 1px solid $color-content-07; + } + + input { + border: none; + color: $color-text-tertiary; + font-size: 14px; + height: 30px; + + &:focus-visible { + outline: none; + } + + &::placeholder { + font-style: normal; + } + } + + .fa { + color: $color-text-tertiary; + font-size: 14px; + } +} \ No newline at end of file diff --git a/sass/common/content/ContentSearch.scss b/sass/common/content/ContentSearch.scss index 2be96edc7..1e9a210a4 100644 --- a/sass/common/content/ContentSearch.scss +++ b/sass/common/content/ContentSearch.scss @@ -19,7 +19,7 @@ button { // sass-lint:disable-line nesting-depth width: 100%; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 13px; font-weight: bold; text-align: left; @@ -56,7 +56,7 @@ &__advanced-filters-text { margin-bottom: 15px; outline: 0; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 13px; cursor: pointer; } @@ -129,7 +129,7 @@ &__search-button { width: 80%; - font-family: "Open Sans"; + font-family: "Inter"; font-weight: normal; } diff --git a/sass/common/form/FormLabel.scss b/sass/common/form/FormLabel.scss index b23d8da41..fe4dd8065 100644 --- a/sass/common/form/FormLabel.scss +++ b/sass/common/form/FormLabel.scss @@ -1,4 +1,6 @@ .FormLabel { + display: flex; + font-family: Inter; &__language-label { margin-right: 5px; @@ -10,4 +12,16 @@ font-size: 8px; vertical-align: super; } + + .btn-link { + font-size: 12px; + &:hover, &:focus { + text-decoration: none; + cursor: pointer; + } + } + + .pficon-info{ + font-size: 12px; + } } diff --git a/sass/common/form/MultiSelectMenuItem.scss b/sass/common/form/MultiSelectMenuItem.scss index 19069fdff..71508fb7e 100644 --- a/sass/common/form/MultiSelectMenuItem.scss +++ b/sass/common/form/MultiSelectMenuItem.scss @@ -13,7 +13,7 @@ &__text { padding-left: 15px; - font-family: "Open Sans"; + font-family: "Inter"; font-style: normal; font-weight: bold; } diff --git a/sass/common/form/RenderTextInput.scss b/sass/common/form/RenderTextInput.scss index 052addc43..15963240f 100644 --- a/sass/common/form/RenderTextInput.scss +++ b/sass/common/form/RenderTextInput.scss @@ -2,6 +2,7 @@ &__input-body { display: flex; border: 1px solid $color-vertical-grey; + border-radius: $radius-xxs; &:focus-within { // sass-lint:disable-line nesting-depth border-color: $color-mid-blue; diff --git a/sass/common/form/SearchForm.scss b/sass/common/form/SearchForm.scss index f04fbe1da..15225c2e3 100644 --- a/sass/common/form/SearchForm.scss +++ b/sass/common/form/SearchForm.scss @@ -1,35 +1,49 @@ .SearchForm { &__container { display: flex; + border: 1px solid $color-content-07; } &__textbox { display: flex; flex: 1; - border: 1px solid $color-ecr-list-icon; border-right: 0; + position: relative; } &__textbox--base { flex: 1; - padding: 0 5px; + padding-inline: 5px 10px; border: 0; outline: none; } - &__button-wrapper { - border: solid 1px $color-ecr-list-icon; - } - &__button { height: 100%; padding-right: 12px; padding-left: 12px; box-shadow: none; + background: none; + border: none; + + &:hover, + &:active, + &:focus, + &:active:hover { + box-shadow: none; + background: none; + border: none; + outline: none; + } } &__button-close { - padding-right: 12px; - padding-left: 12px; + position: absolute; + top: calc((100% - 20px) / 2); + right: 0%; + + &.hidden { + visibility: hidden; + } } } diff --git a/sass/common/form/ToggleButtonGroup.scss b/sass/common/form/ToggleButtonGroup.scss index 23379d920..61aa3fa47 100644 --- a/sass/common/form/ToggleButtonGroup.scss +++ b/sass/common/form/ToggleButtonGroup.scss @@ -7,9 +7,18 @@ } .btn-default.active { - border-color: $color-dark-grey; - background-color: $color-dark-grey; - color: $color-white; + background-color: #fff; + color: $color-primary-text; + } + + .btn-default:hover{ + border: none; + outline: none; + } + + .btn-default:active{ + border: none; + outline: none; } select { diff --git a/sass/component-repository/CategoryFilter.scss b/sass/component-repository/CategoryFilter.scss new file mode 100644 index 000000000..e6fc05412 --- /dev/null +++ b/sass/component-repository/CategoryFilter.scss @@ -0,0 +1,6 @@ +.CategoryFilter { + &__dropdown-btn { + width: 140px; + justify-content: space-between; + } +} \ No newline at end of file diff --git a/sass/component-repository/common/CheckboxGroup.scss b/sass/component-repository/common/CheckboxGroup.scss index ede143774..923ce6616 100644 --- a/sass/component-repository/common/CheckboxGroup.scss +++ b/sass/component-repository/common/CheckboxGroup.scss @@ -1,13 +1,16 @@ .CheckboxGroup { - padding: 12px 28px; + padding: 12px; ul { - padding-left: 0; + display: flex; + flex-direction: column; list-style: none; + padding-left: 0; + row-gap: 12px; } li { - color: $color-black; + height: max-content; input { display: none; @@ -17,25 +20,31 @@ border-color: $color-light-blue; color: $color-light-blue; font-family: FontAwesome; - font-size: 20px; + font-size: 16px; line-height: 15px; - text-indent: -2px; + text-indent: -1px; content: $fa-check-square; } label { cursor: pointer; + display: flex; + align-items: center; + column-gap: 12px; &:before { display: block; - width: 18px; - height: 18px; - margin-right: 20px; + width: 14px; + height: 14px; float: left; - border: 2px solid $color-dark-grey; + border: 1px solid $color-content-07; border-radius: 3px; content: " "; } + + span { + width: max-content; + } } } } diff --git a/sass/component-repository/common/SidebarFilter.scss b/sass/component-repository/common/SidebarFilter.scss index c1401664b..0fd5f039a 100644 --- a/sass/component-repository/common/SidebarFilter.scss +++ b/sass/component-repository/common/SidebarFilter.scss @@ -1,33 +1,33 @@ -.SidebarFilter { - border: solid 1px $color-light-grey-border; - background: $color-white; - text-align: left; +// .SidebarFilter { +// border: solid 1px $color-light-grey-border; +// background: $color-white; +// text-align: left; - &__title { - padding: 20px 15px; - border-bottom: 2px solid $color-extra-light-grey-border; - color: $color-black; - font-family: Open Sans; - font-size: 22px; - font-style: normal; - line-height: normal; - } +// &__title { +// padding: 20px 15px; +// border-bottom: 2px solid $color-extra-light-grey-border; +// color: $color-black; +// font-family: Inter; +// font-size: 22px; +// font-style: normal; +// line-height: normal; +// } - &__body { - .CheckboxGroup { - padding: 20px 15px; - } +// &__body { +// .CheckboxGroup { +// padding: 20px 15px; +// } - li { - margin-bottom: 15px; - } +// li { +// margin-bottom: 15px; +// } - label { - font-weight: normal; +// label { +// font-weight: normal; - &::before { - margin-right: 8px !important; // sass-lint:disable-line no-important - } - } - } -} +// &::before { +// margin-right: 8px !important; // sass-lint:disable-line no-important +// } +// } +// } +// } diff --git a/sass/component-repository/components/BundlePreview.scss b/sass/component-repository/components/BundlePreview.scss index a40d2bdd5..affa398cf 100644 --- a/sass/component-repository/components/BundlePreview.scss +++ b/sass/component-repository/components/BundlePreview.scss @@ -32,7 +32,7 @@ &__bundle-name { margin-top: 8px; color: $color-ecr-list-icon-active; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 16px; font-style: normal; font-weight: 600; @@ -46,7 +46,7 @@ &__hub-name { margin-top: 5px; color: $color-mid-blue; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; font-style: normal; font-weight: normal; @@ -63,7 +63,7 @@ &__description-title { color: $color-ecr-list-icon-active; - font-family: Open Sans; + font-family: Inter; font-size: 12px; font-style: normal; font-weight: bold; @@ -74,7 +74,7 @@ margin-top: 6px; margin-bottom: 35px; color: $color-grey-description; - font-family: Open Sans; + font-family: Inter; font-size: 12px; font-style: normal; font-weight: normal; @@ -113,7 +113,7 @@ margin-top: 4px; margin-right: 19px; color: $color-ecr-list-icon-active; - font-family: Open Sans; + font-family: Inter; font-size: 12px; font-style: normal; font-weight: bold; @@ -128,7 +128,7 @@ // sass-lint:disable bem-depth &__title { color: $color-ecr-list-icon-active; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; font-style: normal; font-weight: 700; @@ -138,7 +138,7 @@ &__version { // sass-lint:disable bem-depth margin-left: 26px; color: $color-ecr-list-icon-active; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; font-style: normal; font-weight: 600; @@ -154,7 +154,7 @@ &__error-message { color: $color-bundle-uninstall-error; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; font-style: normal; font-weight: 400; diff --git a/sass/component-repository/components/ComponentList.scss b/sass/component-repository/components/ComponentList.scss index e7ab3f5a8..abb425187 100644 --- a/sass/component-repository/components/ComponentList.scss +++ b/sass/component-repository/components/ComponentList.scss @@ -1,4 +1,7 @@ .ComponentList { + padding: 20px; + background-color: $color-light-grey-background; + h1 { margin: 0; margin-bottom: 3px; @@ -6,10 +9,15 @@ } &__component { + display: flex; position: relative; margin-bottom: 20px; padding-left: 10px; + @media (max-width: 992px) { + width: 100%; + } + &--even { padding-right: 10px; padding-left: 0; @@ -18,36 +26,48 @@ &__component-wrapper { display: flex; + width: 100%; padding: 16px; - background: $color-light-grey-background; - box-shadow: 0 1px 1px rgba(51, 51, 51, .18); + border: 1px solid rgba(228, 231, 236, 1); + border-radius: 10px; + background-color: #fff; + align-items: center; } &__component-image-wrapper { width: 170px; height: 170px; overflow: hidden; + border-radius: 6px; + @media (max-width: 1200px) { width: 100px; height: 100px; } - & > img { + &>img { width: 100%; height: 100%; object-fit: cover; } } + &__component-content { + width: 50%; + } + &__install-actions { text-align: center; + + .btn-group { + display: flex; + } } &__buttons-container { display: flex; - max-height: 24px; - & > div { + &>div { margin-right: 10px; } } @@ -56,6 +76,7 @@ display: flex; flex-direction: column; justify-content: space-between; + gap: 20px; width: calc(100% - 170px); min-height: 170px; padding-left: 10px; @@ -65,8 +86,29 @@ } h1 { - font-family: Open Sans; - font-size: 18px; + font-family: Inter; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 25px; + } + } + + &__list-body { + display: flex; + justify-content: space-between; + gap: 20px; + width: calc(100% - 170px); + min-height: 170px; + padding-left: 10px; + + @media (max-width: 1200px) { + width: calc(100% - 100px); + } + + h1 { + font-family: Inter; + font-size: 16px; font-style: normal; font-weight: 600; line-height: 25px; @@ -74,26 +116,25 @@ } &__component-category { - color: $color-ecr-component-date; - font-family: Open Sans; - font-size: 14px; + color: $color-brand-primary; + font-family: Inter; + font-size: 12px; font-style: normal; font-weight: normal; line-height: 19px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; + margin: 0 0 6px; } &__component-footer { display: flex; flex-wrap: nowrap; - justify-content: flex-end; - padding-top: 20px; - border-top: solid 1px $color-grey-border; vertical-align: middle; + height: fit-content; - & > div { + &>div { display: flex; } } @@ -122,15 +163,22 @@ &__version-container { display: flex; + align-items: baseline; } &__version { display: block; margin-bottom: 8px; - color: $color-ecr-component-dark-grey; font-size: 14px; font-weight: bold; line-height: normal; + + .badge { + color: rgba(52, 64, 81, 1); + background-color: rgba(242, 244, 247, 1); + padding: 6px; + border-radius: 25px; + } } &__show-install-plan { @@ -140,6 +188,11 @@ &:hover { text-decoration: none; } + + &.btn-link { + padding-left: 6px; + font-size: 12px; + } } &__status { @@ -147,7 +200,7 @@ border: 1px solid $color-ecr-component-installed-button-border; background-color: $color-ecr-component-installed-button; color: $color-white; - font-family: Open Sans; + font-family: Inter; font-size: 12px; font-style: normal; font-weight: 600; @@ -168,9 +221,8 @@ } &__description { - padding-top: 5px; color: $color-ecr-component-text-grey; - font-family: Open Sans; + font-family: Inter; font-size: 12px; line-height: 20px; } @@ -189,17 +241,17 @@ .ComponentListListView { & .ComponentList__list-item { padding: 16px; - background: $color-light-grey-background; - box-shadow: 0 1px 1px rgba(51, 51, 51, .18); + border: 1px solid rgba(228, 231, 236, 1); + border-radius: 10px; + background-color: #fff; } - & .ComponentList__list-item + .ComponentList__list-item { - margin-top: 10px; + & .ComponentList__list-item+.ComponentList__list-item { + margin-top: 20px; } & .ComponentList__install-actions { display: flex; - width: 100%; height: 100%; } } @@ -212,6 +264,14 @@ @media (min-width: 992px) { flex-direction: row; align-items: normal; + width: unset; + } + + + .ComponentListInstallButtons { + .btn-group { + display: flex; + } } @media (max-width: 1536px) { @@ -231,6 +291,7 @@ flex: 1; max-width: 220px; } + //sass-lint:enable class-name-format nesting-depth } } @@ -249,4 +310,4 @@ height: 24px; min-height: 24px; line-height: 24px -} +} \ No newline at end of file diff --git a/sass/component-repository/components/ComponentListPage.scss b/sass/component-repository/components/ComponentListPage.scss index 0e81f8d1d..eae2e3133 100644 --- a/sass/component-repository/components/ComponentListPage.scss +++ b/sass/component-repository/components/ComponentListPage.scss @@ -1,97 +1,41 @@ //sass-lint:disable class-name-format nesting-depth force-element-nesting no-important .ComponentListPage { height: 100%; + scrollbar-gutter: stable; - & > .container-fluid { + &>.container-fluid { height: 100%; padding: 0; - background: $color-grey-background; - & > .container-fluid { + &.container-cards-pf { + margin-top: 0; + } + + &>.container-fluid { padding: 0; } } - & .PageTitle__header { - border-bottom: 0; + .PageTitle { + &__header { + padding-inline: 20px; - h1 { - margin-top: 18px; + &::after { + width: calc(100% + 10px); + right: -10px; + } } } - &__header { - margin-bottom: 20px; - padding: 20px; - padding-bottom: 20px; - border-bottom: solid 2px $color-grey-border; - background: $color-white; - } - &__body { padding: 0 20px 20px 20px; } - &__container { - border: solid 1px $color-light-grey-border; - background: $color-white; - } - - &__container-header { - display: flex; - justify-content: space-between; - height: 72px; - padding: 20px 15px; - border-bottom: 2px solid $color-extra-light-grey-border; - } - - &__container-header-title { - color: $color-black; - font-family: Open Sans; - font-size: 22px; - font-style: normal; - line-height: normal; - } - - &__container-header-actionbar { - display: flex; - - & > div { - padding: 0 20px; - border-left: solid 1px $color-extra-light-grey-border; - } - - & > div:first-child { - display: flex; - border-left: 0; - } - - & > div:last-child { - padding-right: 0; - } - - .FilterType button { - height: 30px; - border: solid 1px $color-ecr-list-icon !important; - border-right: 0 !important; - box-shadow: none; - } - - .ComponentListViewModeSwitcher { - display: flex; - flex-wrap: nowrap; - } - } - &__container-body { padding: 20px 15px; - } - &__refresh-button { - margin-bottom: 20px; - } - - &__refresh-icon { - margin-left: 5px; + .content-view-pf-pagination { + border: 1px solid $color-content-09; + } } -} +} \ No newline at end of file diff --git a/sass/component-repository/components/ComponentListViewModeSwitcher.scss b/sass/component-repository/components/ComponentListViewModeSwitcher.scss index 7bf3aa831..800dca5db 100644 --- a/sass/component-repository/components/ComponentListViewModeSwitcher.scss +++ b/sass/component-repository/components/ComponentListViewModeSwitcher.scss @@ -1,14 +1,17 @@ -.ComponentListViewModeSwitcher__btn { - border: 0; - background: none; - color: $color-ecr-list-icon; - font-size: 20px; +.ComponentListViewModeSwitcher { + display: flex; + flex-wrap: nowrap; + align-items: center; + gap: 0 8px; - &:hover, - &:focus, - &:active, - &--selected { - outline: none; - color: $color-ecr-list-icon-active; + &__btn { + border: 0; + &:hover, + &:focus, + &:active, + &--selected { + outline: none; + color: $color-ecr-list-icon-active; + } } } diff --git a/sass/component-repository/components/ComponentUninstallProcessState.scss b/sass/component-repository/components/ComponentUninstallProcessState.scss index aec4037fb..c7a285120 100644 --- a/sass/component-repository/components/ComponentUninstallProcessState.scss +++ b/sass/component-repository/components/ComponentUninstallProcessState.scss @@ -7,7 +7,7 @@ &__in-progress-body-progress-bar-text { margin-bottom: 13px; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; font-weight: 700; } diff --git a/sass/component-repository/components/HubRegistrySwitcher.scss b/sass/component-repository/components/HubRegistrySwitcher.scss index f82ec6156..f28840e3b 100644 --- a/sass/component-repository/components/HubRegistrySwitcher.scss +++ b/sass/component-repository/components/HubRegistrySwitcher.scss @@ -1,39 +1,36 @@ .HubRegistrySwitcher { +&__container { + margin-bottom: 30px; + padding: 20px; + border: solid 1px $color-light-grey-border; + background: $color-white; +} + &__body { display: flex; - height: 112px; - margin-bottom: 29px; - padding-top: 17px; - padding-right: 19px; - padding-left: 14px; - border: solid 1px $color-light-grey-border; - background: $color-white; + justify-content: space-between; + align-items: center; } &__title { color: $color-ecr-list-icon-active; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 22px; font-style: normal; line-height: 30px; } &__description { - margin-top: 20px; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; font-style: normal; font-weight: 700; - letter-spacing: 0; - line-height: 2px; text-align: left; } &__switcher-label { display: flex; - margin-top: 2px; - margin-right: 10px; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; font-style: normal; font-weight: 700; @@ -71,7 +68,7 @@ &--new { padding-left: 34px; color: $color-mid-blue; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; font-style: normal; font-weight: normal; @@ -105,22 +102,11 @@ &__switcher { display: flex; - margin-top: 10px; - margin-left: auto; + align-items: baseline; + gap: 10px; } } -.BundleGroupAutoComplete { - width: 170px; - margin-right: -20px; - margin-left: -20px; - - div { - input { //sass-lint:disable-line nesting-depth - height: 30px; - } - } -} .EditRegistryModal { width: 800px; diff --git a/sass/component-repository/list/ComponentListActionsWrapper.scss b/sass/component-repository/list/ComponentListActionsWrapper.scss new file mode 100644 index 000000000..d9267850e --- /dev/null +++ b/sass/component-repository/list/ComponentListActionsWrapper.scss @@ -0,0 +1,129 @@ +.ComponentListActions { + &__container-header { + display: flex; + justify-content: space-between; + } + + &__container-header-title { + color: $color-black; + font-family: Inter; + font-size: 22px; + font-style: normal; + line-height: normal; + } + + &__container-header-actionbar { + display: flex; + flex-wrap: wrap; + gap: 20px 8px; + font-size: 12px; + color: $color-text-tertiary; + + .btn { + font-size: 12px; + color: $color-text-tertiary; + } + + .TabBarFilter .btn, + .ComponentListViewModeSwitcher .btn, + .CategoryFilter__dropdown-btn { + background-color: #fff; + border: 1px solid $color-content-07; + + &.active { + color: $color-brand-primary; + background-color: $color-brand-background-primary; + box-shadow: none; + } + } + + .dropdown-toggle { + height: 30px; + } + + & > div:first-child { + display: flex; + align-items: flex-start; + } + + & > div:last-child { + padding-right: 0; + } + + .SearchForm__container { + height: 30px; + border-radius: 0 8px 8px 0; + } + + .TabBarFilter { + align-items: center; + } + + .FilterType button { + border-color: $color-content-07; + border-right: 0; + } + + .TabBarFilter > div, + .ComponentListViewModeSwitcher { + & > span { + display: block; + width: 70px; + text-align: right; + } + } + + & > div:has(.CategoryFilter__dropdown-btn) { + ul { + left: unset; + width: fit-content; + } + } + + .ComponentListActions__refresh-button { + color: #fff; + } + } + + &__container-bundle-group { + input { + height: 28px; + border-radius: 0; + border: none; + font-size: 12px; + padding-block: 0; + box-shadow: none; + + &::placeholder { + font-style: normal; + } + } + + .DropdownTypeahead { + display: flex; + align-items: center; + margin-bottom: 0; + + & > div { + padding: 0; + } + } + + .btn.active{ + height: 30px; + border: none; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .SearchForm { + &__button-wrapper { + display: flex; + } + + &__button-close { + position: unset; + } + } + } +} \ No newline at end of file diff --git a/sass/contents/ContentListCard.scss b/sass/contents/ContentListCard.scss index 1bb86f723..9187c8a72 100644 --- a/sass/contents/ContentListCard.scss +++ b/sass/contents/ContentListCard.scss @@ -3,8 +3,7 @@ position: relative; min-height: 275px; margin: 0 -10px; - padding: 0 20px 20px; - border: $color-pf-black-300 solid 1px; + padding: 0 0px 0px; @media (max-width: 1499px) { height: auto; @@ -20,6 +19,10 @@ .dropdown { float: right; + + .dropdown-menu { + left: -20px; + } } } @@ -31,7 +34,65 @@ } &__table { - margin: 2em 0 0 0; + margin: 0 0 0 0; + } + + .content-view-pf-pagination{ + background-color: #fff + } + + } + + .ContentListCardTable__wrapper { + width: 100%; + overflow-x: auto; + } + + .table-bordered { + border: $color-border-grey solid 1px; + margin: 0; + } + + .table-header { + background-color: #fff; + + td { + border-left: 0; + border-right: 0; + } + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + + th { + padding: 16px; + border-left: 0; + border-right: 0; + border-color: $color-border-grey; + } + } + + .table-row { + td { + border: 1px solid $color-border-grey; + border-left: 0; + border-right: 0; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + max-width: 10px; + } + + .colForResize { + border-left: 1px solid transparent; + border-right: 1px solid transparent; + border-bottom: 1px solid $color-border-grey; } } + + .table-cell { + font-size: 14px; + padding: 16px; + } } diff --git a/sass/contents/Contents.scss b/sass/contents/Contents.scss index e97090022..dd5479b82 100644 --- a/sass/contents/Contents.scss +++ b/sass/contents/Contents.scss @@ -8,7 +8,7 @@ margin-left: 10px; padding-top: 5px; float: right; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; } @@ -35,7 +35,7 @@ } &__table { - font-family: "Open Sans"; + font-family: "Inter"; font-size: 12px; @media (min-width: 991px) { overflow: visible; @@ -53,7 +53,7 @@ &__selected-contents { padding: 10px 8px; background-color: $color-ultra-grey-border; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 13px; > button { diff --git a/sass/contents/ContentsFilter.scss b/sass/contents/ContentsFilter.scss index 4ff1ae76c..f3d9122d2 100644 --- a/sass/contents/ContentsFilter.scss +++ b/sass/contents/ContentsFilter.scss @@ -19,7 +19,7 @@ button { // sass-lint:disable-line nesting-depth width: 100%; background-color: $color-vertical-grey; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 13px; font-weight: bold; text-align: left; @@ -56,7 +56,7 @@ &__advanced-filters-text { margin-bottom: 15px; outline: 0; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 13px; cursor: pointer; } @@ -121,7 +121,7 @@ &__search-button { width: 80%; - font-family: "Open Sans"; + font-family: "Inter"; font-weight: normal; } diff --git a/sass/contents/ContentsStatusCard.scss b/sass/contents/ContentsStatusCard.scss index 1fa6429c8..788a49b66 100644 --- a/sass/contents/ContentsStatusCard.scss +++ b/sass/contents/ContentsStatusCard.scss @@ -1,14 +1,17 @@ +// sass-lint:disable no-extends + .ContentsStatusCard { + @extend .div__border--solid-grey; position: relative; - height: 275px; margin: 0 -10px 20px; - padding: 0 20px 5px; - border: #d1d1d1 solid 1px; + padding: 20px; + border-radius: $spacing-4; + border: $color-border-grey solid 1px; - &__title { - margin-bottom: 0; + h2 { + margin: 0; font-size: 16px; - font-weight: 400; + font-weight: 600; } &__bottom-link { @@ -17,4 +20,4 @@ bottom: 0; padding: 5px; } -} +} \ No newline at end of file diff --git a/sass/contents/JoinCategoriesModal.scss b/sass/contents/JoinCategoriesModal.scss index 808250909..33f5c869d 100644 --- a/sass/contents/JoinCategoriesModal.scss +++ b/sass/contents/JoinCategoriesModal.scss @@ -13,7 +13,7 @@ &__info-text { display: inline-block; padding: 10px; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 13px; } } diff --git a/sass/dashboard/Cards.scss b/sass/dashboard/Cards.scss index c7d6b2f2f..3197336a5 100644 --- a/sass/dashboard/Cards.scss +++ b/sass/dashboard/Cards.scss @@ -1,24 +1,36 @@ -// sass-lint:disable class-name-format nesting-depth +// sass-lint:disable class-name-format nesting-depth no-extends .DashboardPage { + .card-pf-body { + display: flex; + align-items: baseline; + gap: 24px; + + a { + color: $color-text-tertiary; + } + + ::before { + padding-right: 5px; + } + + .card-pf-aggregate-status-container { + display: flex; + gap: 6px; + } + } + .card-pf { - .fa { - margin-right: 5px; - color: $color-icon-gray; + @extend .div__border--solid-grey; + border-radius: $spacing-4; + .fa { &:not(:first-child) { margin-left: 15px; } } + } - .btn { - &.pull-right { - margin-top: -5px; - } - } - - .separator { - margin-right: 5px; - margin-left: 15px; - } + .card-pf-aggregate-status-count { + font-size: 14px; } -} +} \ No newline at end of file diff --git a/sass/dashboard/DashboardPage.scss b/sass/dashboard/DashboardPage.scss index 3e016b8dc..ee4dba3a2 100644 --- a/sass/dashboard/DashboardPage.scss +++ b/sass/dashboard/DashboardPage.scss @@ -1,5 +1,35 @@ +// sass-lint:disable class-name-format nesting-depth + .DashboardPage { - .container-fluid { // sass-lint:disable-line class-name-format + + .card-pf-title { + font-size: 18px; + font-weight: 600; + display: flex; + justify-content: space-between; + align-items: center; + + + .dropdown-toggle { + color: $color-brand-primary; + font-size: 16px; + font-weight: 500; + } + } + + .left-title { + display: flex; + align-items: center; + gap: 10px; + } + + .pull-right > div { + display: flex; + } + + .container-fluid { + + // sass-lint:disable-line class-name-format @media (max-width: 426px) { padding-right: 8px; padding-left: 8px; @@ -9,4 +39,9 @@ padding-right: 8px; } } -} + a { + font-size: 16px; + color: $color-brand-primary; + font-weight: 500; + } +} \ No newline at end of file diff --git a/sass/dashboard/PageStatus.scss b/sass/dashboard/PageStatus.scss index 7219fad54..a862fe3a5 100644 --- a/sass/dashboard/PageStatus.scss +++ b/sass/dashboard/PageStatus.scss @@ -1,14 +1,17 @@ +// sass-lint:disable no-extends + .PageStatus { + @extend .div__border--solid-grey; position: relative; - height: 275px; margin: 0 -10px 20px; - padding: 0 20px 0; - border: $color-pf-black-300 solid 1px; + border-radius: $spacing-4; + padding: 20px; + border: $color-border-grey solid 1px; h2 { - margin-bottom: 0; + margin: 0; font-size: 16px; - font-weight: 400; + font-weight: 600; } &__bottom-link { @@ -17,4 +20,4 @@ bottom: 0; padding: 5px; } -} +} \ No newline at end of file diff --git a/sass/dashboard/PagesList.scss b/sass/dashboard/PagesList.scss index cf989a180..3d51aa8d3 100644 --- a/sass/dashboard/PagesList.scss +++ b/sass/dashboard/PagesList.scss @@ -1,11 +1,10 @@ -// sass-lint:disable class-name-format nesting-depth +// sass-lint:disable class-name-format nesting-depth no-extend .PagesList { position: relative; height: auto; margin: 0 -10px; margin-bottom: 20px; - padding: 0 20px 20px 20px; - border: $color-pf-black-300 solid 1px; + padding: 0px 0px 20px 0px; @media (max-width: 1499px) { height: auto; @@ -16,9 +15,11 @@ } .PagesList__wrapper { - @media (max-width: 769px) { - width: 100%; - overflow-x: auto; + width: 100%; + overflow-x: hidden; + + .tbody{ + overflow-y: scroll; } } @@ -27,12 +28,6 @@ font-weight: 400; } - .btn { - &.pull-right { - margin-bottom: 10px; - } - } - .PagesListTable__table { margin: 2em 0 0 0; } @@ -40,4 +35,53 @@ &__bottom-link { padding: 5px; } + + .table-bordered { + border: $color-border-grey solid 1px; + } + + .table-header { + background-color: #fff; + border-right: 1px solid $color-border-grey; + + + td { + border-left: 0; + border-right: 0; + } + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + + th { + padding: 16px; + border-left: 0; + border-right: 0; + border-color: $color-border-grey; + } + } + + .table-row { + td { + border: 1px solid $color-border-grey; + border-left: 0; + border-right: 0; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + max-width: 10px; + } + + .colForResize { + border-left: 1px solid transparent; + border-right: 1px solid transparent; + border-bottom: 1px solid $color-border-grey; + } + } + + .table-cell { + font-size: 14px; + padding: 16px; + } } diff --git a/sass/dashboard/ViewPermissionNoticeOverlay.scss b/sass/dashboard/ViewPermissionNoticeOverlay.scss index 1a9dab07c..fe63fa927 100644 --- a/sass/dashboard/ViewPermissionNoticeOverlay.scss +++ b/sass/dashboard/ViewPermissionNoticeOverlay.scss @@ -21,4 +21,52 @@ text-align: center; } } + + .content-view-pf-pagination{ + background-color: white; + border: 1px solid $color-border-grey; + border-top:unset; + + .form-group{ + align-items: center; + font-size: 14px; + + .form-control{ + font-size: 14px; + } + + + .dropdown-toggle{ + background-color: transparent; + } + } + + } + + + + .pagination{ + li > a{ + border: none; + outline: none; + vertical-align: middle; + background: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + padding: 16px; + } + + li > a:hover{ + background-color: $color-neutral-grey; + } + + li > a:focus{ + background-color: none; + } + + + } + } diff --git a/sass/database/list/DatabaseListTable.scss b/sass/database/list/DatabaseListTable.scss index f5bbc6b71..ea7af0f7b 100644 --- a/sass/database/list/DatabaseListTable.scss +++ b/sass/database/list/DatabaseListTable.scss @@ -1,5 +1,48 @@ .DatabaseListTable { + .table-bordered { + tr { + border: 1px solid $color-border-grey; + } + + th, td { + border: none; + } + + } + + &__table { - margin: 2em 0 0 + margin: 2em 0 0; + + + + + .table-header { + background-color: #fff; + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + + .table-header { + padding: 16px; + } + } + + tbody{ + .table-row { + td { + background-color: #fff; + text-overflow: ellipsis; + vertical-align: center !important; + padding: 16px; + font-size: 14px; + } + } + } + } + + .UserAuthorityTable__delete-tag-btn{ + justify-self: center; } } diff --git a/sass/ddtable/DDTable.scss b/sass/ddtable/DDTable.scss index 91ec97afe..3558fa93f 100644 --- a/sass/ddtable/DDTable.scss +++ b/sass/ddtable/DDTable.scss @@ -9,3 +9,16 @@ .DDTable__tr--dnd-hover-medium { background: $color-pf-black-400; } + +.DDTable{ + + table{ + margin-bottom: unset !important; + background-color: white; + } + + padding: 16px; + background-color: #F9FAFB; + border: 1px solid $color-content-09; + border-radius: 4px; +} diff --git a/sass/email-config/EmailConfigPage.scss b/sass/email-config/EmailConfigPage.scss index 3293722e0..38b75fa59 100644 --- a/sass/email-config/EmailConfigPage.scss +++ b/sass/email-config/EmailConfigPage.scss @@ -3,13 +3,113 @@ margin-bottom: 20px; } - &__tab { - // sass-lint:disable class-name-format nesting-depth no-important - &.active { - a { - border-bottom-color: $color-light-grey-border !important; + .header-container{ + margin-left: -20px; + margin-right: -20px; + border-bottom: 1px solid $color-border-grey; + margin-bottom: 8px; + + .header-content{ + padding: 8px 20px 0px 20px !important; + display: flex ; + justify-content: space-between; + + .button-group{ + display: flex; + + .btn-default{ + background-color: unset; + box-shadow: none; + border: none; + border-bottom: 2px solid $color-border-grey; + border-radius: unset; + + &:hover{ + border-bottom: 2px solid $color-brand-primary; + color: black; + } + + &.selected{ + border-bottom: 2px solid $color-brand-primary; + color: black; + } + + &:focus{ + outline: unset; + } + } + } + } + } + + .PageTitle{ + margin: unset; + display: flex; + align-items: center; + + &__title{ + margin: unset; + } + + &__content{ + width: fit-content; + margin-right: 16px; + } + + &__header::after { + content: none; + } + } + + .table{ + margin-top: 8px; + thead { + background-color: #fff !important; + background-image: unset; + background: unset; + + th{ + border: unset; + padding: 16px; + } + + + td { + border-left: 0; + border-right: 0; + } + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + } + + tbody{ + tr { + td { + background-color: #fff; + border: 1px solid $color-border-grey; + background-color: #fff !important; + border-left: 0; + border-right: 0; + text-overflow: ellipsis; + vertical-align: center !important; + padding: 16px; + font-size: 14px; + } } } - // sass-lint:enable class-name-format nesting-depth no-important } + + .container-fluid { + padding-bottom: 16px; + } + + // &__tab { + // // sass-lint:disable class-name-format nesting-depth no-important + // &.active, &.selected { + // background-color: red; + // } + // // sass-lint:enable class-name-format nesting-depth no-important + // } } diff --git a/sass/email-config/EmailConfigSenderMgmt.scss b/sass/email-config/EmailConfigSenderMgmt.scss index 19baf6598..a59d882aa 100644 --- a/sass/email-config/EmailConfigSenderMgmt.scss +++ b/sass/email-config/EmailConfigSenderMgmt.scss @@ -2,4 +2,8 @@ &__add-btn { margin-bottom: 5px; } + + .table-bordered { + border: 1px solid $color-border-grey; + } } diff --git a/sass/email-config/EmailConfigSmtpServer.scss b/sass/email-config/EmailConfigSmtpServer.scss new file mode 100644 index 000000000..4886501da --- /dev/null +++ b/sass/email-config/EmailConfigSmtpServer.scss @@ -0,0 +1,20 @@ + .EmailConfigSmtpServer{ + &__form { + .RenderTextInput__input-body { + border-radius: $radius-s; + border-color: $color-content-07; + } + + .RenderRadioInput__toggle-btn { + background-color: #ffffff; + color: $color-text-secondary; + border-color: $color-content-08; + } + + & .active, & .active:hover { + background-color: $color-brand-background-primary; + color: $color-brand-primary; + border-color: $color-content-07; + } + } + } \ No newline at end of file diff --git a/sass/file-browser/list/FilesListTable.scss b/sass/file-browser/list/FilesListTable.scss index 55003bc5e..659a5279f 100644 --- a/sass/file-browser/list/FilesListTable.scss +++ b/sass/file-browser/list/FilesListTable.scss @@ -10,4 +10,58 @@ &__up-link { cursor: pointer; } + + .table{ + border: none; + + tr { + border: 1px solid $color-border-grey; + + &:has(th:only-child > *:empty) { + border: unset; + } + } + + th, td { + border: none; + } + + thead { + background: none; + + th{ + padding: 16px; + + &.center { + text-align: center; + } + } + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + } + + tbody{ + tr { + td { + background-color: #fff; + text-overflow: ellipsis; + vertical-align: middle; + padding: 16px; + font-size: 14px; + + &.center { + display: flex; + justify-content: center; + } + } + + &:hover{ + background-color: $color-row-selected !important; + background: $color-row-selected !important; + } + } + } + } } diff --git a/sass/file-browser/list/ListFilesPage.scss b/sass/file-browser/list/ListFilesPage.scss new file mode 100644 index 000000000..4fff571d3 --- /dev/null +++ b/sass/file-browser/list/ListFilesPage.scss @@ -0,0 +1,13 @@ +.ListFilesPage{ + .btnGroup{ + padding-right:unset ; + .pull-right{ + display: flex; + gap: 8px; + + .btn{ + border-radius: 6px !important; + } + } + } +} \ No newline at end of file diff --git a/sass/fragment/DetailFragmentPage.scss b/sass/fragment/DetailFragmentPage.scss index 37f328327..ae8312758 100644 --- a/sass/fragment/DetailFragmentPage.scss +++ b/sass/fragment/DetailFragmentPage.scss @@ -2,7 +2,6 @@ .DetailFragmentPage { - margin-top: 15px; &__div-search { border-top: 0; @@ -18,4 +17,8 @@ text-transform: capitalize; } + .DetailFragmentTable { + margin-top: 20px; + } + } diff --git a/sass/fragments/common/_FragmentForm.scss b/sass/fragments/common/_FragmentForm.scss index cd49c3b15..b6ed7b8e8 100644 --- a/sass/fragments/common/_FragmentForm.scss +++ b/sass/fragments/common/_FragmentForm.scss @@ -8,3 +8,10 @@ color: $color-pf-black-300; font-size: 12px; } + +.FragmentForm__dropdown { + .dropdown-menu { + left: unset; + right: 0; + } +} \ No newline at end of file diff --git a/sass/fragments/list/_ListFragmentPage.scss b/sass/fragments/list/_ListFragmentPage.scss index 00790287f..8a8084157 100644 --- a/sass/fragments/list/_ListFragmentPage.scss +++ b/sass/fragments/list/_ListFragmentPage.scss @@ -1,33 +1,114 @@ +// sass-lint:disable force-element-nesting, no-qualifying-elements, class-name-format .ListFragmentPage { + font-family: Inter; + .FragmentListTable__table { margin: 2em 0 0 0; - } + } -} + .dropdown-menu { + a { + display: flex; + align-items: center; + color: $color-text-secondary; -// Bootstrap overrides -// sass-lint:disable force-element-nesting, no-qualifying-elements, class-name-format -.ListFragmentPage .nav-tabs > li.ListFragmentPage__header-tab > a { - height: 57px; - line-height: 43px; -} + &:hover { + text-decoration: none; + } + } -.ListFragmentPage .nav-tabs.nav-justified > .active > a { - border-bottom-color: $color-pf-black-300; -} + .danger > a { + color: $color-error-primary; + } + } + + &__toolbar-container { + display: flex; + justify-content: flex-end; + align-items: center; + } + + &__tab-container { + display: flex; + justify-content: flex-start; + column-gap: 8px; + padding-inline: 16px; + } -.ListFragmentPage .nav-tabs.nav-justified > :not(.active) > a { - background-color: $color-pf-black-200; -} + &__header-tab { + display: flex; + align-items: baseline; + color: $color-text-tertiary; + column-gap: 8px; + font-size: 14px; + font-weight: 500; + border-bottom: 2px solid transparent; + padding: 6px 16px; + + &.active, &.active:hover { + color: $color-brand-primary; + border-color: $color-brand-primary; + } -.ListFragmentPage .nav-tabs.nav-justified > :not(.active):hover > a { - background-color: $color-pf-black-700; - color: $color-pf-white; - font-weight: 600; -} + &:hover { + cursor: pointer; + border-color: $color-text-tertiary; + } + } + + .FragmentListContent { + display: flex; + flex-direction: column; + gap: 20px; + padding: 16px; + } + + &__search-container { + display: flex; + justify-content: space-between; + } + + .FragmentSearchForm{ + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + gap: 8px; + + .form-control { + height: 28px; + width: 140px; + font-size: 12px; + padding-block: 0; + + &::placeholder { + font-style: normal; + } + } + + &__select-default-value { + color: $color-mid-grey; + } + } + + .FragmentGrid__box { + .content-view-pf-pagination { + border: 1px solid $color-content-09; + border-top: none; + } + } + + .FragmentGrid__container { + border: 1px solid $color-content-09; + background-color: #F9FAFB; + border-radius: $radius-xxs; + + .content-view-pf-pagination { + border: none; + border-top: 1px solid $color-border-grey; + } + } -.ListFragmentPage .nav-tabs.nav-justified { - border: 1px solid $color-pf-black-300; - border-top: 0; + .SettingsFragmentForm { + padding: 16px; + } } -// sass-lint:enable force-element-nesting, no-qualifying-elements, class-name-format diff --git a/sass/index.scss b/sass/index.scss index 3719b1941..9fcc0ea31 100644 --- a/sass/index.scss +++ b/sass/index.scss @@ -1,184 +1,200 @@ -@import "variables"; -@import "patternfly"; -@import "modules"; -@import "common/patternfly-override"; -@import "internal-page/InternalPage"; -@import "internal-page/PageTitle"; -@import "common/form/FormLabel"; -@import "common/form/FormSectionTitle"; -@import "common/form/DatePicker"; -@import "common/form/SearchForm"; -@import "widgets/common/WidgetForm"; -@import "widgets/common/WidgetIcon"; -@import "widgets/common/IconUploader"; -@import "widgets/common/IconLibrary"; -@import "widgets/config/WidgetConfigPage"; -@import "widgets/common/WidgetPage"; -@import "widgets/list/ListWidgetPage"; -@import "widgets/list/WidgetListTable"; -@import "widgets/list/WidgetListActionToggle"; -@import "widgets/list/WidgetListRow"; -@import "widgets/detail/DetailWidgetElement"; -@import "pages/common/PageStatusIcon"; -@import "pages/common/PageTree"; -@import "pages/common/PageTreeCompact"; -@import "pages/common/RowSpinner"; -@import "pages/common/NewSpinner"; -@import "pages/common/StartupWaitScreen"; -@import "pages/common/PageTreePreview"; -@import "pages/common/MultiSelectRenderer"; -@import "pages/common/PageForm"; -@import "pages/common/FindTemplateModal"; -@import "pages/common/SeoInfo"; -@import "pages/common/PageSettingsForm"; -@import "pages/settings/PageSettings"; -@import "pages/config/ToolbarPageConfig"; -@import "pages/config/ToolbarContentIcon"; -@import "pages/config/WidgetGroupings"; -@import "pages/config/WidgetGrouping"; -@import "pages/config/WidgetGroupingItem"; -@import "pages/config/ContentPages"; -@import "fragments/common/FragmentForm"; -@import "fragments/list/ListFragmentPage"; -@import "fragment/FragmentForm"; -@import "fragment/DetailFragmentPage"; -@import "fragment/FragmentReferenceTable"; -@import "fragment/PageTemplateReferenceTable"; -@import "fragment/WidgetTypeReferenceTable"; -@import "data-types/common/DataTypeStatusIcon"; -@import "data-types/common/DataTypeForm"; -@import "data-types/list/DataTypeListTable"; -@import "pages/config/PageConfigPage"; -@import "pages/config/PageConfigGrid"; -@import "pages/config/PageConfigGridCol"; -@import "pages/config/PageConfigGridRow"; -@import "pages/config/WidgetFrame"; -@import "pages/config/EmptyFrame"; -@import "pages/config/SinglePageSettingsModal"; -@import "pages/config/SinglePageSettingsForm"; -@import "pages/list/PageListSearchTable"; -@import "users/common/UserStatus"; -@import "users/common/UserForm"; -@import "users/common/ProfileImageUploader"; -@import "users/list/UserListTable"; -@import "users/restrictions/RestrictionsForm"; -@import "users/my-profile/MyProfilePage"; -@import "data-models/list/DataModelListTable"; -@import "groups/list/GroupListTable"; -@import "groups/common/GroupForm"; -@import "labels/list/LabelsAndLanguagesPage"; -@import "labels/list/ActiveLangTable"; -@import "labels/list/LabelsTable"; -@import "groups/common/DeleteGroupModal"; -@import "groups/detail/GroupDetailTabPages"; -@import "groups/detail/GroupDetailTabUsers"; -@import "groups/detail/GroupDetailTabWidgetTypes"; -@import "groups/detail/GroupDetailTabContents"; -@import "groups/detail/GroupDetailTabResources"; -@import "categories/list/CategoryTree"; -@import "categories/common/CategoryTreeSelector"; -@import "categories/common/CategoryTreeInput"; -@import "categories/filter/CategoryTreeFilter"; -@import "common/form/RenderRadioInput"; -@import "common/form/DropdownTypeahead"; -@import "common/form/MultiSelectMenuItem"; -@import "common/form/FiltersSelectRenderer"; -@import "common/form/FilterValueOptionSelector"; -@import "common/form/RenderDateFilterInput"; -@import "common/CMSShell"; -@import "common/CMSPageTitle"; -@import "common/cross-browser"; -@import "common/SectionTitle"; -@import "common/CollapsibleSectionTitle"; -@import "common/attributes/AttributesDateSettings"; -@import "common/attributes/AttributeListTable"; -@import "common/attributes/AttributeCheckIcon"; -@import "roles/list/RoleListTable"; -@import "roles/detail/DetailRole"; -@import "common/references/UserRefsTable"; -@import "common/references/GenericRefsTable"; -@import "common/contenttype-attributes/AttributeCheckIcon"; -@import "common/contenttype-attributes/AttributeListTable"; -@import "categories/detail/DetailCategoryTable"; -@import "dashboard/DashboardPage"; -@import "dashboard/Cards"; -@import "dashboard/PageStatus"; -@import "dashboard/PagesList"; -@import "dashboard/ViewPermissionNoticeOverlay"; -@import "dashboard/UserManagementCard"; -@import "dashboard/UxPatternsCard"; -@import "dashboard/LanguagesCard"; -@import "reload-configuration/ReloadConfig"; -@import "database/list/DatabaseListPage"; -@import "database/list/DatabaseListTable"; -@import "database/add/AddDatabaseListTable"; -@import "database/report/ReportDatabaseListDataSource"; -@import "database/report/DatabaseDumpTablePage"; -@import "file-browser/add/CreateFolderForm"; -@import "file-browser/list/FilesListTable"; -@import "file-browser/list/FileBreadcrumb"; -@import "file-browser/upload/UploadFileBrowserForm"; -@import "file-browser/common/CreateTextFileForm"; -@import "activity-stream/Notification"; -@import "profile-types/common/ProfileTypeForm"; -@import "profile-types/list/ProfileTypeListTable"; -@import "component-repository/common/SidebarFilter"; -@import "component-repository/common/CheckboxGroup"; -@import "component-repository/common/StarIcon"; -@import "component-repository/RatingFilterItem"; -@import "component-repository/RatingFilter"; -@import "component-repository/common/TabBarFilter"; -@import "component-repository/ExtraTabBarFilter"; -@import "component-repository/components/ComponentList"; -@import "component-repository/components/ComponentListPage"; -@import "component-repository/components/ComponentListViewModeSwitcher"; -@import "component-repository/components/InstallationPlanModal"; -@import "component-repository/components/InstallationPlanTable"; -@import "component-repository/settings/SettingsList"; -@import "ddtable/DDTable"; -@import "common/form/FilterType"; -@import "page-templates/detail/PageTemplateDetailTable"; -@import "page-templates/list/PageTemplateListTable"; -@import "about/AboutPage"; -@import "license/LicensePage"; -@import "widgets/config/forms/NavigationBarConfigForm"; -@import "tour/index"; -@import "email-config/EmailConfigPage"; -@import "email-config/EmailConfigSenderMgmt"; -@import "pages/config/WidgetGroupingListItem"; -@import "pages/list/PageSearchForm"; -@import "common/form/RenderTextInput"; -@import "common/form/RenderTextAreaInput"; -@import "common/form/RenderListField"; -@import "common/form/ContentTypeAttributeForm"; -@import "common/form/ToggleButtonGroup"; -@import "content-template/ContentTemplateList"; -@import "content-template/AddContentTemplateForm"; -@import "content-type/ContentTypeList"; -@import "content-type/ContentTypeReferenceStatus"; -@import "content-type/ContentTypeForm"; -@import "content-type/AttributesDateSettings"; -@import "content-settings/ContentSettingsGeneral"; -@import "content-settings/ContentSettingsCropRatios"; -@import "content-settings/ContentSettingsCropRatioInput"; -@import "content-settings/ContentSettingsMetadata"; -@import "edit-content/EditContentForm"; -@import "common/RenderVersionText"; -@import "common/StickySave"; -@import "common/cancel-modal/ConfirmCancelModal"; -@import "contents/ContentsFilter"; -@import "contents/Contents"; -@import "contents/JoinCategoriesModal"; -@import "contents/ContentsStatusCard"; -@import "contents/ContentListCard"; -@import "common/content/ContentSearch"; -@import "common/content/ContentFormFieldCollapse"; -@import "widgets/forms/ContentsQueryForm"; -@import "widgets/forms/ContentsFilterModal"; -@import "widgets/forms/SingleContentConfigFormBody"; -@import "pages/config/WidgetGroupingListItem"; -@import "pages/list/PageSearchForm"; -@import "component-repository/components/HubRegistrySwitcher"; -@import "component-repository/components/BundlePreview"; -@import "mfe-container/MfeMenuContainer"; -@import "component-repository/components/ComponentUninstallProcessState"; +@import 'variables'; +@import 'patternfly'; +@import 'modules'; +@import 'common/patternfly-override'; +@import 'internal-page/InternalPage'; +@import 'internal-page/PageTitle'; +@import 'common/form/FormLabel'; +@import 'common/form/FormSectionTitle'; +@import 'common/form/DatePicker'; +@import 'common/form/SearchForm'; +@import 'common/CardList'; +@import 'widgets/common/WidgetForm'; +@import 'widgets/common/WidgetIcon'; +@import 'widgets/common/IconUploader'; +@import 'widgets/common/IconLibrary'; +@import 'widgets/config/WidgetConfigPage'; +@import 'widgets/common/WidgetPage'; +@import 'widgets/list/ListWidgetPage'; +@import 'widgets/list/WidgetListTable'; +@import 'widgets/list/WidgetListActionToggle'; +@import 'widgets/list/WidgetListRow'; +@import 'widgets/detail/DetailWidgetElement'; +@import 'pages/common/PageStatusIcon'; +@import 'pages/common/PageTree'; +@import 'pages/common/PageTreeCompact'; +@import 'pages/common/RowSpinner'; +@import 'pages/common/NewSpinner'; +@import 'pages/common/StartupWaitScreen'; +@import 'pages/common/PageTreePreview'; +@import 'pages/common/MultiSelectRenderer'; +@import 'pages/common/PageForm'; +@import 'pages/common/FindTemplateModal'; +@import 'pages/common/SeoInfo'; +@import 'pages/common/PageSettingsForm'; +@import 'pages/settings/ModalPageSettings'; +@import 'pages/settings/PageSettings'; +@import 'pages/config/ToolbarPageConfig'; +@import 'pages/config/ToolbarContentIcon'; +@import 'pages/config/WidgetGroupings'; +@import 'pages/config/WidgetGrouping'; +@import 'pages/config/WidgetGroupingItem'; +@import 'pages/config/ContentPages'; +@import 'fragments/common/FragmentForm'; +@import 'fragments/list/ListFragmentPage'; +@import 'fragment/FragmentForm'; +@import 'fragment/DetailFragmentPage'; +@import 'fragment/FragmentReferenceTable'; +@import 'fragment/PageTemplateReferenceTable'; +@import 'fragment/WidgetTypeReferenceTable'; +@import 'data-types/common/DataTypeStatusIcon'; +@import 'data-types/common/DataTypeForm'; +@import 'data-types/list/DataTypeListTable'; +@import 'pages/config/PageConfigPage'; +@import 'pages/config/PageConfigGrid'; +@import 'pages/config/PageConfigGridCol'; +@import 'pages/config/PageConfigGridRow'; +@import 'pages/config/WidgetFrame'; +@import 'pages/config/EmptyFrame'; +@import 'pages/config/SinglePageSettingsModal'; +@import 'pages/config/SinglePageSettingsForm'; +@import 'pages/detail/_PagesDetailPage'; +@import 'pages/list/PageListSearchTable'; +@import 'pages/list/PageTreePage'; +@import 'users/common/UserStatus'; +@import 'users/common/UserForm'; +@import 'users/common/ProfileImageUploader'; +@import 'users/list/UserListTable'; +@import 'users/table/UserTable'; +@import 'users/restrictions/RestrictionsForm'; +@import 'users/my-profile/MyProfilePage'; +@import 'data-models/list/DataModelListTable'; +@import 'groups/list/GroupListTable'; +@import 'groups/common/GroupForm'; +@import 'labels/list/LabelsAndLanguagesPage'; +@import 'labels/list/ActiveLangTable'; +@import 'labels/list/LabelsTable'; +@import 'groups/common/DeleteGroupModal'; +@import 'groups/detail/GroupDetailTabPages'; +@import 'groups/detail/GroupDetailTabUsers'; +@import 'groups/detail/GroupDetailTabWidgetTypes'; +@import 'groups/detail/GroupDetailTabContents'; +@import 'groups/detail/GroupDetailTabResources'; +@import 'categories/list/CategoryTree'; +@import 'categories/common/CategoryTreeSelector'; +@import 'categories/common/CategoryTreeInput'; +@import 'categories/filter/CategoryTreeFilter'; +@import 'common/form/RenderRadioInput'; +@import 'common/form/DropdownTypeahead'; +@import 'common/form/MultiSelectMenuItem'; +@import 'common/form/FiltersSelectRenderer'; +@import 'common/form/FilterValueOptionSelector'; +@import 'common/form/RenderDateFilterInput'; +@import 'common/Button'; +@import 'common/CMSShell'; +@import 'common/CMSPageTitle'; +@import 'common/cross-browser'; +@import 'common/Icon'; +@import 'common/DropdownButton'; +@import 'common/SectionTitle'; +@import 'common/Search'; +@import 'common/CollapsibleSectionTitle'; +@import 'common/attributes/AttributesDateSettings'; +@import 'common/attributes/AttributeListTable'; +@import 'common/attributes/AttributeCheckIcon'; +@import 'roles/list/RoleListTable'; +@import 'roles/detail/DetailRole'; +@import 'common/references/UserRefsTable'; +@import 'common/references/GenericRefsTable'; +@import 'common/contenttype-attributes/AttributeCheckIcon'; +@import 'common/contenttype-attributes/AttributeListTable'; +@import 'categories/detail/DetailCategoryTable'; +@import 'dashboard/DashboardPage'; +@import 'dashboard/Cards'; +@import 'dashboard/PageStatus'; +@import 'dashboard/PagesList'; +@import 'dashboard/ViewPermissionNoticeOverlay'; +@import 'dashboard/UserManagementCard'; +@import 'dashboard/UxPatternsCard'; +@import 'dashboard/LanguagesCard'; +@import 'reload-configuration/ReloadConfig'; +@import 'database/list/DatabaseListPage'; +@import 'database/list/DatabaseListTable'; +@import 'database/add/AddDatabaseListTable'; +@import 'database/report/ReportDatabaseListDataSource'; +@import 'database/report/DatabaseDumpTablePage'; +@import 'file-browser/add/CreateFolderForm'; +@import 'file-browser/list/FilesListTable'; +@import 'file-browser/list/ListFilesPage'; +@import 'file-browser/list/FileBreadcrumb'; +@import 'file-browser/upload/UploadFileBrowserForm'; +@import 'file-browser/common/CreateTextFileForm'; +@import 'activity-stream/Notification'; +@import 'profile-types/common/ProfileTypeForm'; +@import 'profile-types/list/ProfileTypeListTable'; +// @import 'component-repository/common/SidebarFilter'; +@import 'component-repository/common/CheckboxGroup'; +@import 'component-repository/common/StarIcon'; +@import 'component-repository/CategoryFilter'; +@import 'component-repository/RatingFilterItem'; +@import 'component-repository/RatingFilter'; +@import 'component-repository/common/TabBarFilter'; +@import 'component-repository/ExtraTabBarFilter'; +@import 'component-repository/components/ComponentList'; +@import 'component-repository/components/ComponentListPage'; +@import 'component-repository/components/ComponentListViewModeSwitcher'; +@import 'component-repository/components/InstallationPlanModal'; +@import 'component-repository/components/InstallationPlanTable'; +@import 'component-repository/list/ComponentListActionsWrapper'; +@import 'component-repository/settings/SettingsList'; +@import 'ddtable/DDTable'; +@import 'common/form/FilterType'; +@import 'page-templates/common/PageTemplateForm'; +@import 'page-templates/detail/PageTemplateDetailTable'; +@import 'page-templates/list/PageTemplateListTable'; +@import 'about/AboutPage'; +@import 'license/LicensePage'; +@import 'widgets/config/forms/NavigationBarConfigForm'; +@import 'tour/index'; +@import 'email-config/EmailConfigPage'; +@import 'email-config/EmailConfigSenderMgmt'; +@import 'email-config/EmailConfigSmtpServer'; +@import 'pages/config/WidgetGroupingListItem'; +@import 'pages/list/PageSearchForm'; +@import 'common/form/RenderTextInput'; +@import 'common/form/RenderTextAreaInput'; +@import 'common/form/RenderListField'; +@import 'common/form/ContentTypeAttributeForm'; +@import 'common/form/ToggleButtonGroup'; +@import 'content-template/ContentTemplateList'; +@import 'content-template/AddContentTemplateForm'; +@import 'content-type/ContentTypeList'; +@import 'content-type/ContentTypeReferenceStatus'; +@import 'content-type/ContentTypeForm'; +@import 'content-type/AttributesDateSettings'; +@import 'content-settings/ContentSettingsGeneral'; +@import 'content-settings/ContentSettingsCropRatios'; +@import 'content-settings/ContentSettingsCropRatioInput'; +@import 'content-settings/ContentSettingsMetadata'; +@import 'edit-content/EditContentForm'; +@import 'common/RenderVersionText'; +@import 'common/StickySave'; +@import 'common/cancel-modal/ConfirmCancelModal'; +@import 'contents/ContentsFilter'; +@import 'contents/Contents'; +@import 'contents/JoinCategoriesModal'; +@import 'contents/ContentsStatusCard'; +@import 'contents/ContentListCard'; +@import 'common/content/ContentSearch'; +@import 'common/content/ContentFormFieldCollapse'; +@import 'widgets/forms/ContentsQueryForm'; +@import 'widgets/forms/ContentsFilterModal'; +@import 'widgets/forms/SingleContentConfigFormBody'; +@import 'pages/config/WidgetGroupingListItem'; +@import 'pages/list/PageSearchForm'; +@import 'component-repository/components/HubRegistrySwitcher'; +@import 'component-repository/components/BundlePreview'; +@import 'mfe-container/MfeMenuContainer'; +@import 'component-repository/components/ComponentUninstallProcessState'; +@import 'pages/common/StatusBadge'; + diff --git a/sass/internal-page/InternalPage.scss b/sass/internal-page/InternalPage.scss index f6147a57c..538b715f4 100644 --- a/sass/internal-page/InternalPage.scss +++ b/sass/internal-page/InternalPage.scss @@ -2,10 +2,10 @@ margin-bottom: 20px; // sass-lint:disable class-name-format - .breadcrumb { - margin-bottom: 0; - border-bottom: 1px solid $color-pf-black-300; - } + // .breadcrumb { + // margin-bottom: 0; + // border-bottom: 1px solid $color-pf-black-300; + // } // sass-lint:enable class-name-format &__page-title { @@ -31,6 +31,7 @@ &__icon { padding-left: 8px; font-size: 15px; + color: $color-text-tertiary; } &__link { @@ -51,7 +52,6 @@ .LanguageSelect { position: relative; - border: solid $color-pf-black-900; border-width: 0 0 0 1px; &__dropdown { @@ -59,8 +59,8 @@ padding-right: 24px; border: 0; outline: none; - background: $color-pf-black; - color: $color-pf-black-300; + background: $color-background-primary; + color: $color-text-tertiary; font-size: 11px; cursor: pointer; appearance: none; @@ -69,7 +69,7 @@ &__dropdown-vmenu { padding-top: 5px; padding-bottom: 5px; - background: $color-vmenu-header-bg-grey; + background: $color-background-primary; font-size: 12px; } @@ -95,39 +95,75 @@ &__fixed-bottom { position: fixed; bottom: 64px; - left: 0; border-bottom: 0; } } // sass-lint:disable force-element-nesting class-name-format no-important .nav-pf-vertical { - width: auto; + width: 214px; + border-right: 1px solid $color-neutral-grey; + padding: 10px 0 0 12px; + top: 54px; .secondary-nav-item-pf > a { - width: 214px; padding-left: 25px; + display: flex; + align-items: center; + + &::after { + font-size: 14px; + padding: 0; + } + } + + .nav-pf-secondary-nav .list-group-item > a { + height: 28px; + margin-left: 10px; + } + + &:not(.collapsed) { + & > .list-group > .list-group-item > a { + display: flex; + column-gap: 14px; + } + + & + .VerticalMenu__secondary-collapse-btn { + left: #{$nav-pf-vertical-width * 2}; + } + & + .VerticalMenu__expand-collapse-btn { + justify-content: flex-end; + text-align: right; + } } &.collapsed { - + .VerticalMenu__secondary-collapse-btn { - left: 76px; + width: $sidebar-collapsed-width; + + .list-group-item.secondary-nav-item-pf { + & > a, &.active > a { + width: fit-content; + + &:hover { + width: fit-content; + } + } } + .VerticalMenu__expand-collapse-btn { - width: 75px; + width: 39px; padding-right: 0 !important; padding-left: 0; - text-align: center; + + a { + width: 24px; + } } .secondary-nav-item-pf > a::after { display: none; } - .nav-pf-secondary-nav .list-group-item > a { - width: 214px; - } } } // sass-lint:enable force-element-nesting class-name-format nesting-depth no-important @@ -147,13 +183,13 @@ top: 40px; bottom: 0; left: #{$nav-pf-vertical-width + 15}; - width: calc(100% - #{$nav-pf-vertical-width} - 15px); + width: calc(100% - #{$nav-pf-vertical-width} - 25px); padding: 0; } .container-pf-nav-pf-vertical.collapsed-nav { //sass-lint:disable-line class-name-format force-element-nesting - left: 75px; - width: calc(100% - 75px); + left: $sidebar-collapsed-width; + width: calc(100% - 50px); } .container-pf-nav-pf-vertical.hidden-nav { //sass-lint:disable-line class-name-format force-element-nesting @@ -161,6 +197,15 @@ width: 100%; } +.navbar-pf-vertical { + background-color: $color-background-primary; + border-bottom: 1px solid $color-neutral-grey; + + .navbar-toggle { + display: none; + } +} + .navbar-brand-txt { //sass-lint:disable-line class-name-format margin-left: 7em; line-height: 36px !important; // sass-lint:disable-line no-important @@ -169,49 +214,40 @@ .navbar-brand-icon { //sass-lint:disable-line class-name-format position: absolute; - top: 18px; + top: 15px; height: 24px; + left: 8px; } .navbar-iconic { //sass-lint:disable-line class-name-format - a.dropdown-toggle { //sass-lint:disable-line class-name-format force-element-nesting no-qualifying-elements - margin-top: 5px; - background: $color-vmenu-header-bg-grey; - color: $color-vmenu-header-text-grey; - } + display: flex; + align-items: center; - a.dropdown-toggle:hover { //sass-lint:disable-line class-name-format force-element-nesting no-qualifying-elements - background: $color-vmenu-header-bg-grey; - color: $color-white; - font-weight: bold; - } + a.dropdown-toggle { //sass-lint:disable-line class-name-format force-element-nesting no-qualifying-elements + background: $color-background-primary; + color: $color-text-tertiary; - a.dropdown-toggle:focus { //sass-lint:disable-line class-name-format force-element-nesting no-qualifying-elements - background: $color-vmenu-header-bg-grey; - color: $color-white; - font-weight: bold; + &:hover, &:focus { + background: $color-background-primary; + color: $color-text-secondary; + font-weight: bold; + } } .HomePageLink__link { - margin-top: 5px; - color: $color-vmenu-header-text-grey; + color: $color-text-tertiary; } .HomePageLink__link:hover { - background: $color-vmenu-header-bg-grey; - color: $color-white; + background: $color-background-primary; + color: $color-text-secondary; font-weight: bold; } .HomePageLink__link:focus { - background: $color-vmenu-header-bg-grey; - color: $color-white; + background: $color-background-primary; font-weight: bold; } - - .LanguageSelect { - margin-top: 15px; - } } // sass-lint:disable force-element-nesting class-name-format nesting-depth no-important @@ -242,10 +278,19 @@ } } -.nav-pf-secondary-nav { - left: 0; - width: #{$nav-pf-vertical-width + 14}; + .collapsed .nav-pf-secondary-nav, .nav-pf-secondary-nav { z-index: 1031; + border: 1px solid $color-neutral-grey; +} + +.collapsed .nav-pf-secondary-nav { + left: $sidebar-collapsed-width; +} + +.nav-pf-secondary-nav { + width: #{$nav-pf-vertical-width + 35}; + left: 212px; + top: 52px; } .nav-item-pf-header { @@ -254,54 +299,101 @@ } .nav-pf-secondary-nav .list-group-item > a { - width: #{$nav-pf-vertical-width + 14}; - margin-left: 0; - padding-left: 52px; + width: #{$nav-pf-vertical-width}; } -.VerticalMenu__secondary-collapse-btn { - position: fixed; - top: 60px; - left: 0; - width: 40px; - height: 48px; - outline: none; - background-color: $color-extra-dark-grey; - color: $color-white; - font-size: 20px; - z-index: 1032; - - &:hover, - &:active, - &:focus, - &:active:focus { + +.VerticalMenu { + + &__secondary-collapse-btn, + &__expand-collapse-btn { outline: none; - background-color: $color-extra-dark-grey; - color: $color-white; + border: none; + box-shadow: none; + background-color: $color-background-primary; + color: $color-text-tertiary; + font-size: 20px; + + &:hover, + &:active, + &:focus, + &:active, + &:active:focus { + outline: none; + border: none; + background-color: $color-background-primary; + box-shadow: none; + } + + + &:hover { + color: $color-light-blue; + } } -} -.VerticalMenu__expand-collapse-btn { - position: fixed; - bottom: 0; - left: 0; - width: 214px; - height: 64px; - padding-right: 20px !important; - outline: none; - background-color: $color-extra-dark-grey; - color: $color-white; - font-size: 20px; - text-align: right; - z-index: 1030; - - &:hover, - &:active, - &:focus, - &:active:focus { - outline: none; - background-color: $color-extra-dark-grey; - color: $color-white; + &__secondary-collapse-btn { + position: fixed; + top: 61px; + left: #{$nav-pf-vertical-width + 30}; + width: 40px; + height: 48px; + z-index: 1032; + } + + + &__expand-collapse-btn { + text-align: center; + position: fixed; + bottom: 0; + left: 0; + width: #{$nav-pf-vertical-width + 10}; + height: 64px; + padding-right: 20px !important; + z-index: 1030; + } + + &__headerBreadcrumbs { + width: fit-content; + + &__icon { + margin-inline: 6px 8px; + } + } + + &__headerContainer { + display: flex; + justify-content: space-between; + align-items: center; + width: calc(100% - 40px); + float: right; + + .breadcrumb { + margin: 0; + padding: 0; + display: flex; + align-items: stretch; + + &.active { + color: $color-text-secondary; + } + + &:not(.active) { + color: $color-text-tertiary; + } + + .BreadcrumbItem{ + font-family: Inter; + font-size: 14px; + font-weight: 600; + + &:nth-child(n + 2)::before { + content: "/"; + color: $color-text-tertiary; + font-size: 14px; + font-weight: 600; + } + } + } } } @@ -320,3 +412,104 @@ background: $color-white; z-index: 2000; } + +.VerticalMenuContainer { + .nav-pf-vertical, + .nav-pf-secondary-nav, + .list-group-item.active > a, + .list-group-item > a { + background-color: $color-background-primary; + } + + .list-group-item.active > a { + color: $color-dark-blue; + } + + .nav-pf-vertical { + .list-group { + display: flex; + flex-direction: column; + justify-content: center; + } + + & > .list-group { + row-gap: 8px; + + & > .list-group-item > a { + display: flex; + align-items: center; + z-index: 1; + } + } + + .list-group-item { + border: none; + margin-block: 2px; + + &:hover, &.active { + .VerticalMenuContainer_Icon { + background-color: $color-light-blue; + } + } + + a { + height: 28px; + color: $color-text-tertiary; + padding: 0; + + .fa { + font-size: 16px; + margin-inline: -2px 0; + } + } + + a, a:focus, a:active, a:hover { + background-color: $color-background-primary; + } + + &.active { + a, a::after { + color: $color-light-blue; + } + + a::before { + width: 28px; + height: 28px; + background: $color-dark-blue; + border-radius: $radius-s; + left: -4px; + z-index: -1; + } + } + } + } +} + +.VerticalMenuContainer_Icon { + content: ''; + width: 20px; + height: 20px; + background-color: $color-dim-grey; + mask-repeat: no-repeat; + + &.Dashboard { + mask: url('../public/icons/dashboard.svg'); + } + + &.Pages { + mask: url('../public/icons/copy.svg'); + } + + &.Contents { + mask: url('../public/icons/file.svg'); + } + + &.Components { + mask: url('../public/icons/app-builder-icon.svg'); + } + + &.Users { + mask: url('../public/icons/users.svg'); + } +} + diff --git a/sass/internal-page/PageTitle.scss b/sass/internal-page/PageTitle.scss index 20bfd2327..5844734ed 100644 --- a/sass/internal-page/PageTitle.scss +++ b/sass/internal-page/PageTitle.scss @@ -1,15 +1,36 @@ .PageTitle { - .PageTitle__header { - margin-bottom: 20px; - border-bottom: 1px solid $color-pf-black-200; + margin-bottom: 20px; + font-family: Inter; + position: relative; + + &__header { + &::after { + content: ""; + position: absolute; + width: calc(100% + 60px); + right: -21px; + border-bottom: 1px solid $color-neutral-grey; + } } .PageTitle__title { - font-weight: bold; + color: $color-text-secondary; + font-size: 16px; + font-weight: 500; + margin-block: 10px; + display: flex; + justify-content: space-between; + align-items: center; + } + + .PageTitle__content { + display: flex; + width: calc(100% - 30px); + justify-content: space-between; + align-items: center; } .PageTitle__icon { - color: $color-pf-black-500; cursor: pointer; } @@ -20,4 +41,4 @@ vertical-align: top; } } -} +} \ No newline at end of file diff --git a/sass/labels/list/ActiveLangTable.scss b/sass/labels/list/ActiveLangTable.scss index c9f43121c..48e1307d8 100644 --- a/sass/labels/list/ActiveLangTable.scss +++ b/sass/labels/list/ActiveLangTable.scss @@ -19,4 +19,9 @@ padding-top: 0; padding-bottom: 0; } + + .center { + display: flex; + justify-content: center; + } } diff --git a/sass/labels/list/LabelsAndLanguagesPage.scss b/sass/labels/list/LabelsAndLanguagesPage.scss index cd75a0033..95b37783e 100644 --- a/sass/labels/list/LabelsAndLanguagesPage.scss +++ b/sass/labels/list/LabelsAndLanguagesPage.scss @@ -1,7 +1,77 @@ .LabelsAndLanguagesPage { - &__header-container { - margin-bottom: 30px; - border-bottom: 1px solid $color-pf-black-200; + .col-xs-6{ + padding-left: 0; + } + + &__header-tabs.nav-tabs{ + position: absolute; + right: 30px; + bottom: 0; + } + + .nav-tabs{ + width: fit-content !important; + display: flex; + justify-content: flex-end; + border: none; + + li{ + background-color: white; + display: flex; + align-items: center; + font-weight: 600; + height: calc(100% - 1px); + border-bottom: 2px solid $color-content-07; + min-width: 40px; + width: fit-content; + justify-content: center; + color: $color-text-tertiary; + + &.active{ + color: $color-primary-text !important; + border-bottom: 2px solid $color-brand-primary !important; + border: none; + outline: none; + + :hover{ + outline: none; + } + + a { + color: $color-primary-text; + } + } + + :hover{ + color: $color-primary-text !important; + cursor: pointer; + } + + :focus{ + outline: none; + border: none !important; + border-bottom: 2px solid $color-brand-primary; + } + + a { + line-height: unset; + padding: 4px 8px 4px 8px; + border: none !important; + color: $color-text-tertiary; + + :focus{ + border: none; + } + + .active{ + border: none !important; + } + + :hover{ + color: $color-primary-text; + } + } + } } &__header-tab { @@ -26,8 +96,149 @@ border-color: $color-pf-black-200; } - .PageTitle__header { - border-bottom: 0; + &__table-container { + padding-bottom: 30px; + + .content-view-pf-pagination { + border-color: $color-border-grey; + } + } + + .languagesAndLabelsHeader{ + display: flex; + justify-content: space-between; + flex-wrap: wrap; + align-items: flex-end; + + .PageTitle { + width: 100%; + position: relative; + } + } + + + .input-group{ + width: fit-content; + display: flex; + align-items: center; + gap: 1rem; + + .form-control{ + max-width: fit-content; + overflow: hidden; + border-radius: 8px !important; + } + + .btn-primary{ + border-radius: 6px; + padding: 6px 8px; + } + } + + .ActiveLangTable, + .LabelsTable{ + .table{ + thead { + background: none; + border: none; + + th { + border-left: none; + border-right: none; + padding: 16px; + } + + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + } + + tr { + border: 1px solid $color-border-grey; + } + + th, td { + border: none; + } + + tbody{ + tr { + td { + background-color: #fff; + text-overflow: ellipsis; + vertical-align: middle; + padding: 16px; + font-size: 14px; + } + } + } + } + } + + .LabelSearchForm{ + display: flex; + flex: 1; + gap: 16px; + align-items: center; + background: unset; + border: unset; + outline: none; + width: 100%; + padding: 8px 8px 8px 20px; + flex-wrap: wrap; + font-family: "Inter"; + + h3{ + margin: unset; + font-size: 14px; + } + + .form-group{ + display: flex; + margin-left: 16px; + margin-bottom: unset; + + .row{ + height: 100%; + display: flex; + align-items: center; + flex: 1; + width: fit-content; + gap: 8px; + flex-wrap: wrap; + + label{ + width: fit-content; + padding: unset; + font-size: 12px; + font-weight: 400; + display: none; + } + + .col-xs-9{ + width: unset; + padding: unset; + } + } + + .col-xs-11{ + width: unset; + } + } + } + + .languageSelectGroup { + display: flex; + padding: 8px; + padding-left: 20px; + align-items: center; + gap: 16px; + + label { + font-size: 14px; + font-family: "Inter"; + } } } diff --git a/sass/mfe-container/MfeMenuContainer.scss b/sass/mfe-container/MfeMenuContainer.scss index dca4c5cef..a9e23f14e 100644 --- a/sass/mfe-container/MfeMenuContainer.scss +++ b/sass/mfe-container/MfeMenuContainer.scss @@ -3,18 +3,23 @@ top: 0; right: 0; left: 0; - height: 60px; - background-color: $color-extra-dark-grey; + height: 50px; + background-color: $color-background-primary; + border: 1px solid $color-neutral-grey; z-index: 1030; + + .navbar-nav.navbar-right li > a { + padding-block: 14px; + } } .MfeMenuContainer__left-menu-container { position: fixed; - top: 60px; + top: 50px; bottom: 0; left: 0; width: 215px; - background-color: $color-extra-dark-grey; + background-color: $color-background-primary; z-index: 1030; overflow-x: hidden; overflow-y: auto; diff --git a/sass/page-templates/common/PageTemplateForm.scss b/sass/page-templates/common/PageTemplateForm.scss new file mode 100644 index 000000000..5b0affa05 --- /dev/null +++ b/sass/page-templates/common/PageTemplateForm.scss @@ -0,0 +1,11 @@ +.PageTemplateForm { + padding-bottom: 20px; + + .form-group { + margin-right: 0; + } + + .FormLabel { + justify-content: flex-end; + } +} \ No newline at end of file diff --git a/sass/page-templates/list/PageTemplateListTable.scss b/sass/page-templates/list/PageTemplateListTable.scss index 188ae5459..790c921c3 100644 --- a/sass/page-templates/list/PageTemplateListTable.scss +++ b/sass/page-templates/list/PageTemplateListTable.scss @@ -2,4 +2,120 @@ &__table { margin-bottom: 0; } -} + + .Page_Template_List_Table { + display: flex; + gap: 8px; + flex-wrap: wrap; + } + + .Page_Template_Button { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + padding: 0; + border: 1px solid transparent; + margin: 0; + background-color: transparent; + + &:focus { + border: 1px solid #7dc3e8 + } + } + + .Page_Template_Button_Active { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + padding: 0; + border: 1px solid transparent; + margin: 0; + background-color: transparent; + border: 1px solid #7dc3e8 + } + + .Page_Template_Preview_Container { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + } + + .Page_Template_Preview_Content { + width: 187px; + height: fit-content; + min-height: 127px; + background: rgba(240, 246, 255, 1); + border: 1px solid rgba(204, 224, 255, 1); + position: relative; + } + + .PageConfigGridRow { + border: none; + } + + .PageConfigGridRow { + border: none; + } + + .Page_Template_Preview_Actions { + position: absolute; + right: 10px + } + + .Page_Config_Grid_Container { + padding: 10px 40px; + height: 100%; + + .PageConfigGridCol--container { + display: flex; + flex-direction: column; + gap: 2px; + height: 100%; + min-height: 0 !important; + border: none; + + .PageConfigGridRow { + border: none; + } + + .PageConfigGridRow { + border: none; + + span { + display: none; + } + } + } + + .PageConfigGridRow { + gap: 2px; + } + + .PageConfigGrid { + height: 100%; + padding: 2px; + border-radius: 4px; + background-color: #ffffff; + } + + .PageConfigGridCol--frame { + gap: 2px; + min-height: 0 !important; + padding: 0.5px; + } + + .EmptyFrame { + border-style: solid; + background-color: #bbb; + border-radius: 4px; + padding: 0; + } + + .EmptyFrame__frame-name { + display: none; + } + } +} \ No newline at end of file diff --git a/sass/pages/common/FindTemplateModal.scss b/sass/pages/common/FindTemplateModal.scss index 9c4a5a081..629c6a236 100644 --- a/sass/pages/common/FindTemplateModal.scss +++ b/sass/pages/common/FindTemplateModal.scss @@ -4,12 +4,15 @@ padding: 0; list-style: none; overflow-y: auto; + height: fit-content; + max-height: 450px; } &__template-list-button { - padding: 0; - border: 0; - background: transparent; + padding: 10px; + border: 1px solid #CCE0FF; + border-radius: 4px; + background-color: $color-background-primary; } &__template-list-li { @@ -31,6 +34,41 @@ &__modal { width: 672px; + // background-color: purple; + + + .modal-content { + padding: 24px 20px; + display: flex; + flex-direction: column; + gap: 16px; + border-radius: 8px; + + .modal-header { + background: none; + padding: 0; + + .modal-title { + font-size: 18px; + font-weight: 600; + } + } + + + .modal-body { + display: flex; + flex-direction: column; + gap: 16px; + padding: 0; + } + + .modal-footer { + display: flex; + justify-content: flex-end; + padding: 0; + margin-top: 0; + } + } } &__caption { @@ -38,7 +76,6 @@ } &__search-input { - width: 50%; - margin: 22px; + border-radius: $radius-s; } -} +} \ No newline at end of file diff --git a/sass/pages/common/PageForm.scss b/sass/pages/common/PageForm.scss index e49272d7b..e14c00efc 100644 --- a/sass/pages/common/PageForm.scss +++ b/sass/pages/common/PageForm.scss @@ -22,4 +22,16 @@ content: "\f192"; vertical-align: middle; } + + + .form-group .mobile-left { + text-align: left; + } + + .FormLabel{ + display: flex; + align-items: center; + justify-content: flex-start; + text-align: left; + } } \ No newline at end of file diff --git a/sass/pages/common/PageStatusIcon.scss b/sass/pages/common/PageStatusIcon.scss index 4e6f83611..93eeef2b0 100644 --- a/sass/pages/common/PageStatusIcon.scss +++ b/sass/pages/common/PageStatusIcon.scss @@ -1,11 +1,12 @@ + .PageStatusIcon--unpublished { - color: $color-unpublished; + background-color: $color-unpublished; } .PageStatusIcon--published { - color: $color-published; + background-color: $color-published-600; } .PageStatusIcon--draft { - color: $color-draft; + background-color: $color-draft; } diff --git a/sass/pages/common/PageTree.scss b/sass/pages/common/PageTree.scss index cfdfd17aa..39d5e8aa0 100644 --- a/sass/pages/common/PageTree.scss +++ b/sass/pages/common/PageTree.scss @@ -1,12 +1,35 @@ .PageTree { + + .PageTree__drag-handle { width: 30px; - height: 29px; + height: 30px; padding: 0; + background-color: transparent !important; + color: $color-brand-primary !important; + box-shadow: unset !important; + + &:active { + background-color: transparent !important; + } + + &:focus { + background-color: transparent !important; + } + + &:hover:active { + background-color: transparent !important; + } + } + + .PageTree__no-drag { + .PageTree__drag-handle { + display: none; + } } - &__no-drag { + &__no-drag { button { cursor: default; opacity: 0; @@ -35,10 +58,6 @@ margin-left: 10px; } - .TreeNodeFolderIcon { - color: $color-pf-light-blue-400; - } - &__icons-label { outline: 0; cursor: pointer; @@ -50,6 +69,12 @@ } } + .PageTree__container { + display: flex; + align-items: center; + font-size: 14px; + } + .PageTreeActionMenuButton, .PageTreeActionMenuButton:focus { height: 18px; @@ -68,20 +93,92 @@ } } +.Button { + font-weight: 600; +} + .PageStatusIcon { - line-height: 24px; + width: 8px; + height: 8px; } .PageTree__displayed-in-menu { line-height: 24px; } + + .header-container { + display: flex; + align-items: center; + gap: 20px; + } + + .table-bordered { + border: $color-border-grey solid 1px; + } + + + + .table-header { + background-color: #fff; + border-bottom: 1px solid $color-border-grey; + + td { + border: 1px solid $color-border-grey; + border-left: 0; + border-right: 0; + border-bottom: 0; + } + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + + th { + padding: 16px; + border-left: 0; + border-right: 0; + border-bottom: 0; + border-color: $color-border-grey; + } + } + + .table-row { + border-bottom: 1px solid $color-border-grey; + + td { + border: 0 + } + + .colForResize { + border-left: 1px solid transparent; + border-right: 1px solid transparent; + border-bottom: 1px solid $color-border-grey; + } + + &:hover { + .PageTree__page-name { + color: $color-brand-primary !important + } + + .TreeNodeFolderIcon { + color: $color-brand-primary; + } + } + } + + .table-cell { + padding-inline: 16px !important; + padding-block: 8px !important; + } } + // Bootstrap overrides // sass-lint:disable force-element-nesting, no-qualifying-elements, class-name-format -.table-bordered > tbody > tr > td.PageTree__tree-column-td { +.table-bordered>tbody>tr>td.PageTree__tree-column-td { padding: 0; line-height: 28px; } -// sass-lint:enable force-element-nesting, no-qualifying-elements, class-name-format + +// sass-lint:enable force-element-nesting, no-qualifying-elements, class-name-format \ No newline at end of file diff --git a/sass/pages/common/PageTreeCompact.scss b/sass/pages/common/PageTreeCompact.scss index 6f6f059a4..4c85375df 100644 --- a/sass/pages/common/PageTreeCompact.scss +++ b/sass/pages/common/PageTreeCompact.scss @@ -55,7 +55,7 @@ &.table > tbody > &__row--selected { &, &:hover { - background-color: $color-dragitem-bg; + color:$color-neutral-grey; } } // sass-lint:enable force-element-nesting nesting-depth no-qualifying-elements class-name-format @@ -79,15 +79,17 @@ // Bootstrap overrides // sass-lint:disable force-element-nesting, no-qualifying-elements, class-name-format -.PageTreeCompact.table > tbody > tr:hover, -.PageTreeCompact.table > tbody > tr:hover > td, -.PageTreeCompact.table > tbody > tr:hover > th { - background-color: $color-dragitem-bg; -} +// .PageTreeCompact.table > tbody > tr:hover, +// .PageTreeCompact.table > tbody > tr:hover > td, +// .PageTreeCompact.table > tbody > tr:hover > th { +// background-color: $color-neutral-grey; +// } .PageTreeCompact.table > tbody > tr > td { padding: 10px 0; border-top: 0; - color: $color-white; + font-weight: 600; + color: $color-primary-text; + vertical-align: middle; } // sass-lint:enable force-element-nesting, no-qualifying-elements, class-name-format diff --git a/sass/pages/common/SeoInfo.scss b/sass/pages/common/SeoInfo.scss index e69f717da..abe8c6090 100644 --- a/sass/pages/common/SeoInfo.scss +++ b/sass/pages/common/SeoInfo.scss @@ -6,17 +6,35 @@ } li.active a { - background-color: $color-pf-black-200; + background-color: white; color: $color-pf-black; font-weight: bold; } } // sass-lint:enable no-qualifying-elements, nesting-depth, force-element-nesting, class-name-format + .form-group{ + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; + } + + .FormLabel{ + display: flex; + align-items: center; + flex: 1; + justify-content: flex-start; + text-align: left; + } + &__section { margin-bottom: 40px; padding: 20px 0; - background-color: $color-pf-black-200; + + .RenderTextInput{ + border-radius: 4px; + } } &__addmetadata { diff --git a/sass/pages/common/StatusBadge.scss b/sass/pages/common/StatusBadge.scss new file mode 100644 index 000000000..f033c1ca0 --- /dev/null +++ b/sass/pages/common/StatusBadge.scss @@ -0,0 +1,50 @@ +.StatusBadge--unpublished { + color: $color-unpublished; +} + +.StatusBadge--published { + color: $color-published; +} + +.StatusBadge--draft { + color: $color-draft; +} + +.StatusBadge { + align-items: center; + gap: $spacing-4; + padding: 2px 10px 2px 10px; + border-radius: 30px; + font-size: 12px; + width: fit-content; + text-transform: capitalize; +} + +.StatusBadge-container--published { + background-color: $color-green-light-new; + color: $color-published-600; +} +.StatusBadge-container--unpublished { + background-color: $color-unpublished-light; + color: $color-unpublished-new; +} +.StatusBadge-container--draft { + background-color: $color-draft-200; + color: $color-draft-500; +} + +.StatusBadge-circle { + width: 6.67px; + height: 6.67px; + border-radius: 50%; +} + +.StatusBadge-circle--published { + background-color: $color-published-600; +} +.StatusBadge-circle--draft { + background-color: $color-draft-500; +} +.StatusBadge-circle--unpublished { + background-color: $color-unpublished-new; +} diff --git a/sass/pages/config/ContentPages.scss b/sass/pages/config/ContentPages.scss index 498df4806..f70c61de2 100644 --- a/sass/pages/config/ContentPages.scss +++ b/sass/pages/config/ContentPages.scss @@ -8,15 +8,41 @@ &__pagetree-searchbar { display: flex; - width: 100%; + align-items: center; + gap: 4px; + border: 1px solid $color-content-07; + border-radius: $radius-xxs; + + input { + border: none; + color: $color-text-tertiary; + font-size: 14px; + height: 30px; + box-shadow: none; + + &::placeholder { + font-style: normal; + } + } + + &:has(input:focus) { + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(0, 136, 206, 0.6); + + input:focus { + box-shadow: unset; + } + } } // sass-lint:disable no-important class-name-format force-element-nesting &__pagetree-searchbtn.btn { - border: 1px solid $color-border-gray !important; - border-left: 0 !important; + color: $color-text-tertiary; + border: none; outline: none !important; box-shadow: none !important; + background: none; + height: 100%; + border-radius: $radius-xxs; } // sass-lint:enable no-important class-name-format force-element-nesting @@ -25,16 +51,16 @@ align-items: center; justify-content: space-between; padding: 10px 20px; - border-top: 1px solid $color-black; - border-bottom: 1px solid $color-black; - color: $color-white; + border-top: 1px solid $color-neutral-grey; + border-bottom: 1px solid $color-neutral-grey; + color: $color-primary-text; font-size: 14px; } &__toggler { display: inline-block; margin-right: 10px; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 13px; line-height: 1.66666667; @@ -45,19 +71,16 @@ &__pagetree-addbtn { background-color: $color-light-blue-2; - color: $color-white; // sass-lint:disable nesting-depth force-element-nesting &:hover { background-color: $color-light-blue-hover; - color: $color-white; } &:focus, &:focus:hover { outline: none; background-color: $color-light-blue-active; - color: $color-white; } // sass-lint:enable nesting-depth force-element-nesting } @@ -71,6 +94,8 @@ &__page-name { cursor: pointer; } + + // sass-lint:enable nesting-depth } } @@ -79,8 +104,6 @@ &__search-table { & .table { margin-top: 0; - border: 1px solid $color-black; - color: $color-white; } & thead, @@ -91,22 +114,22 @@ & tr { &.selected, &:hover { - background-color: $color-dragitem-bg; + background-color: $color-dark-blue; } } & th, & td { - border: 1px solid $color-black !important; + border: none; } & .dropdown-kebab-pf .btn { - color: $color-white !important; + color: $color-primary-text !important; } & .table-view-pf-pagination { background: none; - color: $color-white; + color: $color-primary-text; } } // sass-lint:enable nesting-depth no-qualifying-elements force-element-nesting class-name-format no-important diff --git a/sass/pages/config/EmptyFrame.scss b/sass/pages/config/EmptyFrame.scss index 22518365a..f752b0a15 100644 --- a/sass/pages/config/EmptyFrame.scss +++ b/sass/pages/config/EmptyFrame.scss @@ -2,19 +2,38 @@ width: 100%; height: 100%; padding: 3px 8px; - border: 1px dashed $color-pf-black-400; background: $color-pf-black-100; color: $color-pf-black-400; + border-radius: 4px; + display: flex; + justify-content: center; + align-items: center; + &--drag-hover { - border: 1px solid $color-pf-orange-300; + border: 1.5px solid $color-brand-primary; background: $color-pf-black-200; } + + .main-frame { + display: flex; + margin-left: 10px; + padding: 6px; + background-color: $color-pf-black-400; + color: $color-pf-black-100; + font-size: 11px; + font-weight: 600; + border-radius: 4px; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + } } .EmptyFrame--main-frame { .EmptyFrame__frame-name:after { - display: inline; + display: flex; margin-left: 10px; padding: .2em .6em .3em; background-color: $color-pf-black-400; @@ -28,3 +47,5 @@ vertical-align: baseline; } } + + diff --git a/sass/pages/config/PageConfigGrid.scss b/sass/pages/config/PageConfigGrid.scss index 0cb4a65e5..629aca1e6 100644 --- a/sass/pages/config/PageConfigGrid.scss +++ b/sass/pages/config/PageConfigGrid.scss @@ -1,5 +1,5 @@ .PageConfigGrid { width: 100%; - border: 1px solid $color-pf-black-400; border-radius: 1px; + background-color: $color-border-grey; } diff --git a/sass/pages/config/PageConfigGridCol.scss b/sass/pages/config/PageConfigGridCol.scss index 67ef8e5b6..6636d28a4 100644 --- a/sass/pages/config/PageConfigGridCol.scss +++ b/sass/pages/config/PageConfigGridCol.scss @@ -1,8 +1,13 @@ .PageConfigGridCol { +background-color: $color-white; +border: 1px dashed $color-neutral-grey; + &.PageConfigGridCol--frame { flex-grow: 1; min-height: 80px; + padding: 8px; + border: 0; } &.PageConfigGridCol--hole { diff --git a/sass/pages/config/PageConfigGridRow.scss b/sass/pages/config/PageConfigGridRow.scss index 1d68d0093..582e0f481 100644 --- a/sass/pages/config/PageConfigGridRow.scss +++ b/sass/pages/config/PageConfigGridRow.scss @@ -2,4 +2,8 @@ display: flex; flex-grow: 1; width: 100%; + + &:not(:last-child) { + border-bottom: 1px dashed $color-neutral-grey; + } } diff --git a/sass/pages/config/PageConfigPage.scss b/sass/pages/config/PageConfigPage.scss index efe40c2da..be5af75c6 100644 --- a/sass/pages/config/PageConfigPage.scss +++ b/sass/pages/config/PageConfigPage.scss @@ -3,60 +3,148 @@ height: calc(100vh - 74px); max-height: calc(100vh - 74px); overflow-y: auto; + display: flex; + justify-content: space-between; + flex-direction: column; + padding-left: 0px; } &__tabs { - margin-top: 10px; + margin-top: 0px; + + .nav-tabs{ + .__tabContainer{ + display: flex; + align-items: center; + gap: 8px; + + svg{ + width:20px; + height:20px; + } + } + + li > a { + border-bottom: 2px solid $color-border-gray; + border-top: none; + border-right: none; + border-left: none; + outline:none; + font-weight: 500; + } + + li > a:hover, a:focus,a:active { + outline: none; + border-bottom: 2px solid $color-primary; + border-top: none; + border-right: none; + border-left: none; + } + + li.active > a{ + border-bottom: 2px solid $color-blue-brand-primary; + color: $color-blue-brand-primary; + border-top: none; + border-right: none; + border-left: none; + + } + } + + .tab-content{ + padding-left: 20px; + } } &__title { padding-bottom: 10px; - border-bottom: solid 1px #000; font-size: 16px; - font-weight: bold; + font-weight: 600; + color: $color-primary-text; + } + + &__title_container{ + display: flex; + align-items: center; + width: 100%; } - &__toolbar-row { - margin-bottom: 5px; + &__tabHeader{ + display: flex; + flex: 1; + align-items: center; + justify-content: space-between; + + + flex-wrap: wrap; } &__btn-group--trans { - padding-bottom: 5px; + display: flex; + flex-wrap: wrap; .pull-right .btn { // sass-lint:disable-line force-element-nesting class-name-format margin-left: 12px; } } - &__btn-icon--svg { - padding-right: 8px; - } - - &__btn-icon--svg-right { - padding-left: 8px; - } - &__bottom-options { - position: fixed; - right: 67px; - bottom: 5px; - left: 5px; - z-index: 11; + margin-top: 100px; + width: 100%; - .pull-right .btn:not(.dropdown-toggle) { // sass-lint:disable-line force-element-nesting class-name-format - margin-left: 20px; + .pull-right{ + display: flex; + align-items: center; + gap: 20px; } } &__bottom-options--tbar { margin: 0 20px; - padding: 8px 14px; + padding: 6px 7px 0px 7px; background-color: $color-pf-white; - box-shadow: 0 2px 4px rgba(0, 0, 0, .25); + width: 100%; + + display: flex; + justify-content: space-between; + align-items: center; + border-top: 1px solid $color-content-07; + + .left-btn-group{ + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 16px; + } + + .dropdown-btn-title{ + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; + } + } + + .active { + .PageConfigPage__btn-icon--svg.lucide{ + color: inherit; + } + } + + .Button.btn-outlined-primary, .btn-outlined-primary:hover { + color: $color-brand-primary; + font-size: 14px; + + &:focus { + outline: none; + } } .PageStatusIcon { margin-right: 10px; + width: 8px; + height: 8px; + border-radius: 50%; } &__default-applied-label { @@ -71,7 +159,7 @@ } &__on-the-fly-label { - margin-right: 5px; + margin:0px; } &__publishing { @@ -133,6 +221,7 @@ } .PageConfigPage__side-widget { + background-color: white; position: fixed; left: initial; width: 48px; diff --git a/sass/pages/config/ToolbarPageConfig.scss b/sass/pages/config/ToolbarPageConfig.scss index c6ee24a00..69d904b71 100644 --- a/sass/pages/config/ToolbarPageConfig.scss +++ b/sass/pages/config/ToolbarPageConfig.scss @@ -3,6 +3,8 @@ .ToolbarPageConfig { position: relative; width: calc(100% + 20px); + font-family: "Inter", sans-serif; + &__collapse-main { position: absolute; @@ -10,9 +12,9 @@ left: 0; width: 45px; height: 45px; - outline: none; - background-color: $color-black; - color: $color-white; + outline: none !important; + background-color: $color-white; + color: $color-primary-text; text-align: center; box-shadow: none; @@ -26,13 +28,14 @@ &:focus { outline: none; - background-color: $color-black; - color: $color-white; + background-color: $color-white; + color: $color-primary-text; } + + &:hover { - background-color: $color-dragitem-bg; - color: $color-mid-blue; + color: $color-primary-text; } // sass-lint:enable class-name-format nesting-depth } @@ -41,6 +44,23 @@ position: relative; height: 100%; overflow: auto; + + .btn-default{ + border: none; + outline: none; + } + + .btn:hover{ + background-color: white; + } + + .btn-default:focus{ + box-shadow: none; + } + + + + } &__tab-main { @@ -48,8 +68,11 @@ // sass-lint:disable class-name-format force-element-nesting nesting-depth no-qualifying-elements ul.nav { - border-bottom-color: $color-black; - background-color: $color-dragitem-bg; + background-color: $color-white; + outline: none; + border: none; + border-bottom: 1px solid $color-neutral-grey; + &::before { display: block; @@ -62,15 +85,22 @@ min-width: 108px; height: 45px; background-color: transparent; + outline: none; & > a { width: 100%; - padding: 13px 10px; + padding: 13px 0px 13px 0px; border-color: transparent; - color: $color-white; - font-size: 12px; + color: $color-text-tertiary; + font-size: 14px; font-weight: bold; text-align: center; + cursor: pointer; + + &:focus,:focus-visible{ + outline: none; + border: none; + } .fa { margin-right: 5px; @@ -81,32 +111,29 @@ &:hover { border-color: transparent; - color: $color-mid-blue; + color: $color-primary-text; .fa { - color: $color-mid-blue; + color: $color-primary-text; } } } - &.active { - border: 1px solid $color-black; - border-bottom: transparent; - } - &.active a { - height: calc(100% + 1px); border-top: 0; border-color: transparent; - background-color: $color-sidebar-dark-bg; - color: $color-white; + background-color: #FFF; + color: $color-primary-text; + height: calc(100% + 1px); + border-bottom: 1px solid $color-neutral-grey; + color: $color-brand-primary; &:hover { - color: $color-white; + color: $color-brand-primary; } .fa { - color: $color-mid-blue; + color: $color-primary-text; } } } @@ -116,9 +143,9 @@ &__drawer-pf-sidebar-right { height: 100%; - background-color: $color-sidebar-dark-bg; - box-shadow: 0 6px 12px rgba(3,3,3,.175); + background-color: #FFF; z-index: 10; + border-left: 1px solid $color-neutral-grey } &__drawer-pf-sidebar-right-expanded { @@ -187,9 +214,14 @@ // sass-lint:disable class-name-format force-element-nesting nesting-depth no-qualifying-elements .ToolbarPageConfig__collapse-main { width: 48px; + .fa { - color: $color-mid-blue; + color: $color-black; + } + + .fa:hover{ + color: $color-brand-primary; } } @@ -232,6 +264,10 @@ .tab-content { display: none; + + .active{ + padding: 20px; + } } } // sass-lint:enable class-name-format force-element-nesting nesting-depth no-qualifying-elements diff --git a/sass/pages/config/WidgetFrame.scss b/sass/pages/config/WidgetFrame.scss index e52dfc0e0..e653f3dcd 100644 --- a/sass/pages/config/WidgetFrame.scss +++ b/sass/pages/config/WidgetFrame.scss @@ -3,47 +3,105 @@ width: 100%; height: 100%; margin: 0; - padding: 2px; - border: 1px dashed $color-pf-black-400; + padding: 8px; + background-color: $color-grey-background-tertiary; + border-radius: 4px; + &__content { left: 10px; width: 100%; + padding: 8px; height: 100%; - padding: 5px; - border: 1px solid $color-pf-black-600; - border-radius: 3px; + border: 1.5px solid $color-border-primary; + border-radius: 4px; color: $color-pf-black-800; text-align: center; cursor: move; + background-color: $color-white; + outline: none; + display: flex; + align-items: center; + flex-direction: row-reverse; + justify-content: center; + gap: 20px; } &__frame-name { - position: absolute; - left: 10px; color: $color-pf-black-400; } - &__menu-button { - position: absolute; - top: 2px; - right: 10px; + .content-widget{ + display: flex; + width: fit-content; + gap: 16px; + align-items: center; + justify-content: space-between; + flex:1 + } + + .main-frame { + display: flex; + padding: 6px; + background-color: $color-brand-primary; + color: $color-pf-black-100; + font-size: 11px; + font-weight: 600; + line-height: 1; + border-radius: 4px; + text-align: center; + white-space: nowrap; + vertical-align: baseline; } + + + + &__descriptor { display: flex; - flex-direction: column; + flex-direction: row; justify-content: center; + align-items: center; + flex-wrap: wrap; height: 100%; + border-color: $color-brand-primary; + gap:8px; + font-size: 14px; + font-weight: 500; + color: $color-brand-primary; + + .WidgetIconContainer{ + width: 25px; + height: 25px; + background-color: $color-background-icons; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + + + .fa{ + height: 13px; + color: $color-brand-primary; + font-size: 0.94em; + } + + img{ + height: 13px; + filter: invert(24%) sepia(91%) saturate(2456%) hue-rotate(211deg) brightness(100%) contrast(95%); + } + } + } &--drag-hover { - border: 1px solid $color-pf-orange-300; - background: $color-pf-black-200; + border: 1.5px solid $color-brand-primary; } } .WidgetFrame--main-frame { + min-height: 120px; // Main frame label .WidgetFrame__frame-name:after { display: inline; @@ -70,6 +128,10 @@ .WidgetFrame--status-removed { background: $color-pf-black-100; + .content-widget{ + justify-content: center; + } + .WidgetFrame__content { border-color: transparent; color: $color-pf-black-400; diff --git a/sass/pages/config/WidgetGrouping.scss b/sass/pages/config/WidgetGrouping.scss index 2f29dc5c7..cb6a936c8 100644 --- a/sass/pages/config/WidgetGrouping.scss +++ b/sass/pages/config/WidgetGrouping.scss @@ -7,6 +7,8 @@ padding-top: 10px; border: 0; overflow: hidden; + gap: 10px; + flex-wrap: wrap; } &__item-area.odd::after { // sass-lint:disable-line class-name-format force-element-nesting @@ -16,6 +18,6 @@ } &:last-of-type { - border-bottom: 1px solid $color-black; + border-bottom: 1px solid $color-neutral-grey; } } diff --git a/sass/pages/config/WidgetGroupingItem.scss b/sass/pages/config/WidgetGroupingItem.scss index 2f1857b4b..6c582fffb 100644 --- a/sass/pages/config/WidgetGroupingItem.scss +++ b/sass/pages/config/WidgetGroupingItem.scss @@ -2,8 +2,21 @@ width: calc(50% - 20px); margin-bottom: 10px; border: 0; - background-color: $color-dragitem-bg; - overflow: hidden; + cursor: grab; + + + + .icon-container{ + background-color:$color-grey-background-tertiary; + padding: 20px; + border-radius: 6px; + width: 100%; + justify-content: center; + align-items: center; + display: flex; + border: 3px solid $color-border-grey + + } // sass-lint:disable class-name-format nesting-depth &.list-group-item:last-of-type { @@ -35,6 +48,22 @@ line-height: 1; text-transform: capitalize; } + + &__description-container{ + margin: 0; + text-align: center; + width: 100%; + padding: 8px 16px 8px 16px; + display: flex; + align-items: center; + justify-content: center; + + + + a{ + color:$color-text-tertiary; + font-weight: 600; + } // sass-lint:disable class-name-format force-element-nesting &__main.list-view-pf-main-info { @@ -45,7 +74,7 @@ .list-view-pf-left { display: block; margin: 0 auto; - padding-right: 0; + padding-right: 0 !important; color: $color-dark-white; } @@ -57,6 +86,13 @@ .list-view-pf-description { display: block; margin-top: 10px; + display: flex; + justify-content: center; + align-items: center; + flex: 1; + width: 100% !important; + color:$color-text-tertiary; + padding: 15px; } a { @@ -66,8 +102,7 @@ } // sass-lint:enable class-name-format force-element-nesting - &__description { - margin: 0; - text-align: center; - } + + +} } diff --git a/sass/pages/config/WidgetGroupingListItem.scss b/sass/pages/config/WidgetGroupingListItem.scss index 0f24a2dbe..6630dacba 100644 --- a/sass/pages/config/WidgetGroupingListItem.scss +++ b/sass/pages/config/WidgetGroupingListItem.scss @@ -4,7 +4,14 @@ height: 50px; margin-bottom: 3px; border: 0; - background-color: $color-dragitem-bg; + background-color: transparent; + cursor: grab; + + &:hover{ + background-color: $color-neutral-grey; + } + + &__wrapper { display: flex; @@ -16,7 +23,7 @@ display: flex; align-items: center; margin-left: 30px; - color: $color-dark-white; + color: $color-text-tertiary; & > img { filter: invert(73%) sepia(38%) saturate(11%) hue-rotate(39deg) brightness(103%) contrast(102%); @@ -27,14 +34,15 @@ display: flex; align-items: center; margin-left: 20px; - font-family: "Open Sans"; + font-family: "Inter"; font-weight: 400; line-height: 18px; text-align: center; } a { - color: $color-dark-white; + color: $color-text-tertiary; + font-weight: 600; font-size: 14px; } } diff --git a/sass/pages/config/WidgetGroupings.scss b/sass/pages/config/WidgetGroupings.scss index 7e1b546a0..8f2567b00 100644 --- a/sass/pages/config/WidgetGroupings.scss +++ b/sass/pages/config/WidgetGroupings.scss @@ -1,7 +1,7 @@ @import "../../patternfly.scss"; .WidgetGroupings { - background-color: $color-sidebar-dark-bg; + background-color: #FFF; &__right-menu-title { display: flex; @@ -31,7 +31,7 @@ display: flex; flex: 1; align-items: center; - justify-content: center; + justify-content: flex-start; margin-left: 10px; } @@ -44,7 +44,7 @@ } &--selected { - color: $color-white; + color: $color-brand-primary; } } diff --git a/sass/pages/detail/_PagesDetailPage.scss b/sass/pages/detail/_PagesDetailPage.scss new file mode 100644 index 000000000..be42bc3e6 --- /dev/null +++ b/sass/pages/detail/_PagesDetailPage.scss @@ -0,0 +1,5 @@ +.PagesDetailPage { + &__toolbar-row { + padding-block: 4px 10px; + } +} \ No newline at end of file diff --git a/sass/pages/list/PageListSearchTable.scss b/sass/pages/list/PageListSearchTable.scss index c8dca5b32..586a77cea 100644 --- a/sass/pages/list/PageListSearchTable.scss +++ b/sass/pages/list/PageListSearchTable.scss @@ -1,21 +1,52 @@ .PageListSearchTable { - &__table { - margin: 2em 0 0 0; - } + .table-bordered { + border: none; + margin: 0; + + tr { + border: 1px solid $color-border-grey; + } - &__th-lg { - width: 45%; + th, td { + border: none; + } } - &__th-md { - width: 25%; + .table-header { + background-color: #fff; + + td { + border-left: 0; + border-right: 0; + } + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + + th { + padding: 16px; + border-left: 0; + border-right: 0; + } } - &__th-sm { - width: 10%; + .table-row { + td { + border-left: 0; + border-right: 0; + + } + + .colForResize { + border-left: 1px solid transparent; + border-right: 1px solid transparent; + border-bottom: 1px solid $color-border-grey; + } } - &__th-xs { - width: 5%; + .table-cell { + font-size: 14px; + padding: 16px; } } diff --git a/sass/pages/list/PageSearchForm.scss b/sass/pages/list/PageSearchForm.scss index fadcb954e..1915cc326 100644 --- a/sass/pages/list/PageSearchForm.scss +++ b/sass/pages/list/PageSearchForm.scss @@ -1,15 +1,53 @@ .PageSearchForm { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 10px; + padding-bottom: 20px; + + h3 { + margin: 0; + font-size: 14px; + } + + .form-group { + margin-block: 0; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 10px; + + .form-control { + max-width: 320px; + } + + .Search{ + background-color: white; + } + + .dropdown-toggle { + min-width: 180px; + } + + .dropdown-menu>li>a { + min-width: 178px; + } + } + &__filter-searchby { position: relative; margin-left: 20px; padding-right: 0; + display: flex; - .dropdown { // sass-lint:disable-line class-name-format nesting-depth + .dropdown { + // sass-lint:disable-line class-name-format nesting-depth width: 100%; } } - &__filter-searchby-label.label.label-default { // sass-lint:disable-line class-name-format force-element-nesting + &__filter-searchby-label.label.label-default { + // sass-lint:disable-line class-name-format force-element-nesting display: block; position: absolute; top: 0; @@ -21,15 +59,17 @@ z-index: 1; } - &__filter-searchby-dropdown.btn { // sass-lint:disable-line class-name-format force-element-nesting + &__filter-searchby-dropdown.btn { + // sass-lint:disable-line class-name-format force-element-nesting width: calc(100% - 1px); height: 25px; margin-right: 5px; text-align: left; - .caret { // sass-lint:disable-line class-name-format + .caret { + // sass-lint:disable-line class-name-format margin-top: 5px; float: right; } } -} +} \ No newline at end of file diff --git a/sass/pages/list/PageTreePage.scss b/sass/pages/list/PageTreePage.scss new file mode 100644 index 000000000..19c7dc534 --- /dev/null +++ b/sass/pages/list/PageTreePage.scss @@ -0,0 +1,19 @@ +.PageTreePage { + &__btn-clear-container{ + margin-bottom: 20px; + } + .pageTreeSearch{ + padding: 16px; + background-color: #F9FAFB; + border: 1px solid $color-content-09; + border-radius: 4px; + margin-top: 12px; + margin-bottom: 16px; + flex-wrap: wrap; + } + + .PageSearchForm{ + padding-bottom: unset; + + } +} \ No newline at end of file diff --git a/sass/pages/settings/ModalPageSettings.scss b/sass/pages/settings/ModalPageSettings.scss new file mode 100644 index 000000000..f51e26ca4 --- /dev/null +++ b/sass/pages/settings/ModalPageSettings.scss @@ -0,0 +1,135 @@ +.ModalPageSettings { + display: flex; + justify-items: flex-end; + font-family: Inter; + + .modal-dialog { + margin: 0; + display: grid; + min-height: 100vh; + width: 500px; + + .modal-content { + padding: 32px 24px 24px 24px; + + .modal-header { + background-color: transparent; + padding: 0; + + .modal-title { + font-size: 20px; + font-weight: 500; + color: $color-text-secondary; + } + + .close { + font-size: 30px; + } + } + } + + .modal-body { + padding: 0; + + .col-xs-12 { + padding-inline: 0; + // padding-inline: 10px; + } + + .form-group { + display: flex; + flex-direction: column; + margin: 0; + padding-bottom: 8px; + row-gap: 8px; + + &>div { + width: 100%; + display: flex; + } + + &:nth-child(n+5)>div { + padding-inline: 0; + } + + &:has(.bootstrap-switch) { + flex-direction: row; + align-items: center; + padding-block: 16px; + + &>div:nth-child(1n) { + text-align: start; + } + + &>div:nth-child(2n) { + justify-content: flex-end; + width: fit-content; + } + } + + div:has(.pull-right) { + justify-content: flex-end; + } + + label { + font-size: 14px; + font-weight: 500; + } + + &:not(:nth-last-child(-n+1)) { + border-bottom: 1px solid $color-content-08; + } + + &:nth-last-child(-n+4) { + display: flex; + } + } + + &__required-icon { + margin-left: 3px; + color: $color-pf-black-800; + font-size: 9px; + } + + &__popover-icon { + color: $color-brand-primary; + } + + .btn-group > .RenderRadioInput__toggle-btn { + &:first-child { + border-top-left-radius: $radius-xxs; + border-bottom-left-radius: $radius-xxs; + } + + &:last-child { + border-top-right-radius: $radius-xxs; + border-bottom-right-radius: $radius-xxs; + } + } + + label, .text-right { + font-size: 14px; + } + + .RenderRadioInput__toggle-btn { + background-color: $color-background-primary; + color: $color-text-secondary; + border: 1px solid $color-content-08; + box-shadow: none; + -webkit-box-shadow: none; + font-size: 14px; + font-weight: 600; + + &.active { + background-color: #F0F6FF; + color: $color-brand-primary; + border: 1px solid $color-content-07; + } + } + + .bootstrap-switch { + width: fit-content; + } + } + } +} \ No newline at end of file diff --git a/sass/pages/settings/PageSettings.scss b/sass/pages/settings/PageSettings.scss index 31939e501..6c91df951 100644 --- a/sass/pages/settings/PageSettings.scss +++ b/sass/pages/settings/PageSettings.scss @@ -1,9 +1,59 @@ -.PageSettings__required-icon { - margin-left: 3px; - color: $color-pf-black-800; - font-size: 9px; +.PageSettings { + font-family: Inter; + + &__required-icon { + margin-left: 3px; + color: $color-pf-black-800; + font-size: 9px; + } + + &__popover-icon { + color: $color-brand-primary; + } + + .btn-group > .RenderRadioInput__toggle-btn { + &:first-child { + border-top-left-radius: $radius-xxs; + border-bottom-left-radius: $radius-xxs; + } + + &:last-child { + border-top-right-radius: $radius-xxs; + border-bottom-right-radius: $radius-xxs; + } + } + + label, .text-right { + font-size: 14px; + } + + .RenderRadioInput__toggle-btn { + background-color: $color-background-primary; + color: $color-text-secondary; + border: 1px solid $color-content-08; + box-shadow: none; + -webkit-box-shadow: none; + font-size: 14px; + font-weight: 600; + + &.active { + background-color: #F0F6FF; + color: $color-brand-primary; + border: 1px solid $color-content-07; + } + } + + .form-group { + display: flex; + align-items: center; + margin-bottom: 0; + padding-block: 16px; + + &:not(:nth-last-child(-n+1)) { + border-bottom: 1px solid $color-content-08; + } + + } } -.PageSettings__popover-icon { - color: $color-pf-blue-500; -} \ No newline at end of file + diff --git a/sass/patternfly.scss b/sass/patternfly.scss index 9e11199cd..3ffb958de 100644 --- a/sass/patternfly.scss +++ b/sass/patternfly.scss @@ -1,5 +1,5 @@ -@import "~react-bootstrap-typeahead/css/Typeahead"; -@import "~patternfly/dist/sass/patternfly/variables"; +@import '~react-bootstrap-typeahead/css/Typeahead'; +@import '~patternfly/dist/sass/patternfly/variables'; // breakpoints $screen-sm-min: 768px; @@ -13,73 +13,87 @@ $color-rating-selected: #dff3fe; $color-rating-filter-star-empty: #979797; $color-rating-filter-star-filled: #f1c857; $color-icon-gray: #939597; -$color-dark-grey: #4D5258; -$color-dark-white: #D1D1D1; -$color-light-blue: #39A5DC; -$color-light-blue-2: #00A0DF; +$color-dark-grey: #4d5258; +$color-dark-white: #d1d1d1; +$color-light-blue: #39a5dc; +$color-light-blue-2: #00a0df; $color-light-blue-hover: #0188bd; $color-light-blue-active: #0176a4; $color-black: #000000; $color-white: #ffffff; -$color-sidebar-filter-bg-grey: #E7E7E7; -$color-sidebar-filter-border-grey: #DEDEDE; -$color-ecr-component-date: #00B9F7; +$color-sidebar-filter-bg-grey: #e7e7e7; +$color-sidebar-filter-border-grey: #dedede; +$color-ecr-component-date: #00b9f7; $color-ecr-component-text-grey: #828282; -$color-ecr-component-tab-bar-bg-grey: #D8D8D8; -$color-ecr-component-dark-grey: #4F4F4F; -$color-ecr-component-installed-button: #3F9C35; -$color-ecr-component-installed-button-border: #E0E0E0; +$color-ecr-component-tab-bar-bg-grey: #d8d8d8; +$color-ecr-component-dark-grey: #4f4f4f; +$color-ecr-component-installed-button: #3f9c35; +$color-ecr-component-installed-button-border: #e0e0e0; $color-ecr-component-inprogress-button: #f1c857; $color-ecr-component-failed-button: #c45500; -$color-ecr-error-text: #A61302; +$color-ecr-error-text: #a61302; $color-ecr-list-icon-active: #363636; -$color-bundle-uninstall-error: #D30909; -$color-ecr-list-icon: #BBBBBB; -$color-ecr-component-border: #C3C3C3; -$color-vmenu-header-bg-grey: #1D1D1D; +$color-bundle-uninstall-error: #d30909; +$color-ecr-list-icon: #bbbbbb; +$color-ecr-component-border: #c3c3c3; +$color-vmenu-header-bg-grey: #1d1d1d; $color-vmenu-header-text-grey: #c1c1c1; $dark-color-separator: #aaabad; $light-color-separator: #e5e5e5; $color-row-selected: #def3ff; -$color-primary: #002F87; +$color-primary: #002f87; $color-primary-dark: #032a73; -$color-published: #6CA100; -$color-unpublished: #A6A6A6; -$color-draft: #F0AB00; -$color-mid-blue: #0088CE; -$color-mid-green: #3BB800; -$color-mid-orange: #FCA907; -$color-mid-blue-semi: rgba(0,136,206,.6); +$color-published: #6ca100; +$color-unpublished: #a6a6a6; +$color-draft: #f0ab00; +$color-mid-blue: #0088ce; +$color-mid-green: #3bb800; +$color-mid-orange: #fca907; +$color-mid-blue-semi: rgba(0, 136, 206, 0.6); $color-row-selected: #def3ff; -$color-tour-primary: #00A0DF; -$color-border-gray: #BBBBBB; -$color-sidebar-dark-bg: #393F44; +$color-tour-primary: #00a0df; +$color-blue-brand-primary:#1A75FF; +$color-border-gray: #bbbbbb; +$color-sidebar-dark-bg: #393f44; $color-dragitem-bg: #292e34; -$color-transparent-black: rgba(0,0,0,.1); +$color-transparent-black: rgba(0, 0, 0, 0.1); $color-grey-background: #f5f5f5; $color-grey-border: #dadada; -$color-light-grey-border: #E3E3E3; -$color-extra-light-grey-border: #F4F4F4; -$color-light-grey-background: #FAFAFA; -$color-extra-dark-grey: #1D1D1D; -$color-grey-description: #72767B; +$color-light-grey-border: #e3e3e3; +$color-extra-light-grey-border: #f4f4f4; +$color-light-grey-background: #fafafa; +$color-extra-dark-grey: #1d1d1d; +$color-grey-description: #72767b; $color-dump-table-code: #f4f5f7; +$color-published-600: #39ac73; +$color-green-new: #39c67b; +$color-green-light-new: #ebf9f2; +$color-draft-500: #ffb21a; +$color-draft-400: #fbd26a; +$color-draft-200: #faf1d9; +$color-unpublished-new: #637083; +$color-unpublished-light: #d8d8d8; +$color-grey-background-tertiary:#F2F4F7; +$color-border-primary:#99C2FF; +$color-background-icons: #F0F6FF; + + //FontAwesome icons -$fa-check: "\f00c"; -$fa-exclamation: "\f12a"; -$fa-spinner: "\f110"; -$fa-ban: "\f05e"; -$fa-adjust: "\f042"; -$fa-sitemap: "\f0e8"; -$fa-angle-right: "\f105"; -$fa-angle-double-left: "\f100"; -$fa-angle-double-right: "\f101"; -$fa-times: "\f00d"; -$fa-check-square: "\f14a"; -$fa-check-square-o: "\f046"; -$fa-square: "\f0c8"; -$fa-square-o: "\f096"; +$fa-check: '\f00c'; +$fa-exclamation: '\f12a'; +$fa-spinner: '\f110'; +$fa-ban: '\f05e'; +$fa-adjust: '\f042'; +$fa-sitemap: '\f0e8'; +$fa-angle-right: '\f105'; +$fa-angle-double-left: '\f100'; +$fa-angle-double-right: '\f101'; +$fa-times: '\f00d'; +$fa-check-square: '\f14a'; +$fa-check-square-o: '\f046'; +$fa-square: '\f0c8'; +$fa-square-o: '\f096'; // Bootstrap custom styles // sass-lint:disable class-name-format @@ -97,6 +111,15 @@ $fa-square-o: "\f096"; background: $color-pf-black-100; } +.bootstrap-switch { + border-radius: $radius-xxs; + border: 1px solid $color-content-07; + + & .bootstrap-switch-handle-on.bootstrap-switch-primary { + background-color: $color-brand-primary; + } +} + .btn-transparent { border: 0; outline: none; @@ -116,34 +139,80 @@ $fa-square-o: "\f096"; } .btn { - padding: 2px 12px; - border: 0 !important; // sass-lint:disable-line no-important + padding: 4px 8px; + // border: 0 !important; // sass-lint:disable-line no-important background-image: none; + display: flex; + align-items: center; + gap: 10px; + justify-content: center; + border-radius: 6px; + font-size: 14px; + box-shadow: none; + + &:focus, &:focus:hover, &:active { + outline: none; + } } + .btn-primary, .btn-primary:active, .btn-primary:focus { - background-color: $color-primary !important; // sass-lint:disable-line no-important + background-color: $color-brand-primary !important; // sass-lint:disable-line no-important + color: $color-background-icons; } .btn-primary:hover { - background-color: $color-primary; + background-color: $color-brand-primary; } .btn-primary:hover:active { background-color: $color-primary-dark !important; // sass-lint:disable-line no-important } + + +.btn-link { + font-size: 16px; + + &.secondary { + color: $color-content-3; + } +} + +.btn-outlined-primary{ + border: 1.5px solid $color-brand-primary; + border-radius: 4px; + background-color: #FFF; + color: $color-brand-primary; + + &:focus{ + outline: none; + } +} + +.btn-outlined-secondary{ + border: 1.5px solid $color-content-07; + border-radius: 4px; + background-color: #FFF; + color: $color-primary-text; + box-shadow: none; + + &:focus, &:focus:hover { + outline: none; + } +} + .CodeMirror { - border: 1px solid $color-pf-black-400; + border: 1px $color-pf-black-400 solid; } .has-error { .CodeMirror, &.CodeMirror { border: 1px solid $color-pf-red; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px $color-pf-red-100; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px $color-pf-red-100; } } @@ -152,7 +221,7 @@ $fa-square-o: "\f096"; margin-left: 0; } -.no-gutter > [class*="col-"] { +.no-gutter > [class*='col-'] { padding-right: 0; padding-left: 0; } @@ -191,4 +260,100 @@ $fa-square-o: "\f096"; overflow: hidden; } +.div__border--solid-grey { + border: 1px solid $color-neutral-grey; + box-shadow: 0 1px 2px rgba(28, 39, 49, 0.08); // sass-lint:disable-line leading-zero +} + +.form-control { + border: 1px solid $color-content-07; + border-radius: $radius-s; + font-size: 16px; + font-weight: 400; + height: fit-content; + padding: 6px; +} + +.content-view-pf-pagination{ + background-color: white; + + .form-group{ + align-items: center; + font-size: 14px; + + .form-control{ + font-size: 14px; + } + + input { + text-align: center; + } + } +} + +.dropdown-toggle { + background-color: transparent; + + &:has(.fa-ellipsis-v:first-child){ + color: $color-text-tertiary !important; + + &:hover, &:active, &:focus { + color: $color-brand-primary !important; + text-decoration: none; + }} +} + +.pagination{ + li > a{ + border: none; + outline: none; + vertical-align: middle; + background: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + padding: 16px; + } + + .disabled{ + a,a:hover{ + background: none; + } + } + + li > a:hover{ + background-color: $color-neutral-grey; + box-shadow: none; + background: none; + } + + li > a.disabled{ + background: none; + } +} + +.modal-footer { + display: flex; + justify-content: flex-end; +} + +a, a:hover { + color: $color-brand-primary; + } + +.popover { + color: $color-text-secondary; + border: none; + border-radius: 8px; + box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.13); +} + +* { + font-family: Inter; +} + + + + // sass-lint:enable class-name-format diff --git a/sass/reload-configuration/ReloadConfig.scss b/sass/reload-configuration/ReloadConfig.scss index 417a27cf5..450f344cd 100644 --- a/sass/reload-configuration/ReloadConfig.scss +++ b/sass/reload-configuration/ReloadConfig.scss @@ -19,4 +19,10 @@ } // sass-lint:enable force-element-nesting, no-qualifying-elements, class-name-format + &__footer { + display: flex; + justify-content: center; + padding-top: 20px; + } + } diff --git a/sass/tour/index.scss b/sass/tour/index.scss index 37b3f9f02..f26f3989e 100644 --- a/sass/tour/index.scss +++ b/sass/tour/index.scss @@ -11,7 +11,7 @@ padding-left: 20px; background-color: $color-black; color: $color-white; - font-family: "Open Sans"; + font-family: "Inter"; font-size: 13px; font-weight: 600; line-height: 17.7px; @@ -26,7 +26,7 @@ padding-left: 20px; background-color: $color-white; color: $color-ecr-list-icon-active; - font-family: "Open Sans"; + font-family: "Inter"; &--dark { background-color: rgba(41, 46, 52, 1); // sass-lint:disable-line variable-for-property diff --git a/sass/users/common/UserForm.scss b/sass/users/common/UserForm.scss index 8bf75ad8c..8dd823206 100644 --- a/sass/users/common/UserForm.scss +++ b/sass/users/common/UserForm.scss @@ -3,7 +3,6 @@ &__content-edit { margin-bottom: 15px; padding: 10px 0; - border: 1px solid $color-pf-black-300; background-color: $color-pf-black-150; } @@ -12,6 +11,102 @@ } } -.UserSearchForm { - background-color: $color-white; +.UserListPage{ + + .formRow{ + display: flex; + border: none; + outline: none; + + .col-xs-6{ + border: none; + outline: none; + } + + .well{ + border: none; + outline: none; + padding: 0; + box-shadow: none; + margin-bottom: 11px; + + + h3{ + margin-top: 10px; + } + } + + .UserSearchForm { + background-color: $color-white; + display: flex; + flex: 1; + justify-content: flex-start; + gap: 20px; + + + + .row{ + display: flex; + align-items: center; + } + + .form-group{ + display: flex; + margin: 0 !important; + border: none; + + input{ + padding: 6px 0px 6px 6px; + width: 100%; + min-width: 220px; + font-size: 14px; + font-style: normal; + } + } + } + + } + + .content-view-pf-pagination{ + background-color: white; + + .form-group{ + align-items: center; + font-size: 14px; + + .form-control{ + font-size: 14px; + } + + + .dropdown-toggle{ + background-color: transparent; + } + } + + } + + .pagination{ + li > a{ + border: none; + outline: none; + vertical-align: middle; + background: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + padding: 16px; + } + + li > a:hover{ + background-color: $color-neutral-grey; + box-shadow: none; + background: none; + } + + + } + } + diff --git a/sass/users/my-profile/MyProfilePage.scss b/sass/users/my-profile/MyProfilePage.scss index d17414315..267b08c16 100644 --- a/sass/users/my-profile/MyProfilePage.scss +++ b/sass/users/my-profile/MyProfilePage.scss @@ -2,7 +2,6 @@ .MyProfilePage { height: 100%; margin-bottom: 0; - background-color: $color-grey-background; &__tab { margin-top: 32px; @@ -10,8 +9,7 @@ } &__header { - padding: 20px; - border-bottom: solid 2px $color-grey-border; + padding-inline: 20px; background-color: $color-white; } @@ -34,9 +32,6 @@ } & .PageTitle__title { - margin-top: 40px; - margin-bottom: 0; - & .pull-right { margin-left: 22px; float: none !important; @@ -52,8 +47,8 @@ &__body { margin: 21px; padding: 29px 21px; - border: solid 1px $color-grey-border; - background: $color-white; + border: solid 1px $color-border-grey; + border-radius: $radius-xxs; & .form-horizontal { height: 100%; diff --git a/sass/users/restrictions/RestrictionsForm.scss b/sass/users/restrictions/RestrictionsForm.scss index 257b31d07..9fe6019a3 100644 --- a/sass/users/restrictions/RestrictionsForm.scss +++ b/sass/users/restrictions/RestrictionsForm.scss @@ -1,17 +1,26 @@ // sass-lint:disable class-name-format nesting-depth .UserRestrictionsPage { + font-family: Inter; + .form-horizontal { + .form-group .mobile-left { + text-align: left; + } + .control-label { text-align: left; } .RenderTextInput { display: inline-block; - max-width: 69px; } .AppendedLabel { margin-left: 5px; } + + .btn-primary { + padding-inline: 16px; + } } } diff --git a/sass/users/table/UserTable.scss b/sass/users/table/UserTable.scss new file mode 100644 index 000000000..283855f64 --- /dev/null +++ b/sass/users/table/UserTable.scss @@ -0,0 +1,54 @@ +.UserTable { +margin: 0; + + &.table-bordered { + border-color: $color-border-grey; + margin: 0; + } + + + .table-header { + background-color: #fff; + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + + th { + padding: 16px; + } + } + + .table-row { + td { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + max-width: 10px; + } + + .colForResize { + border-left: 1px solid transparent; + border-right: 1px solid transparent; + border-bottom: 1px solid $color-border-grey; + } + } + + .table-cell { + padding: 16px; + border-left: 0; + border-right: 0; + border-color: $color-border-grey; + } +} + +.UserTableWrapper { + width: 100%; + overflow-x: auto; + overflow-y: scroll; + max-height: 390px; + + .content-view-pf-pagination { + border-color: $color-border-grey; + } +} \ No newline at end of file diff --git a/sass/variables.scss b/sass/variables.scss index 8848dd85a..30504278d 100644 --- a/sass/variables.scss +++ b/sass/variables.scss @@ -1,16 +1,51 @@ -$color-black-semi: rgba(0,0,0,.075); +$color-black-semi: rgba(0, 0, 0, 0.075); $color-offwhite: #f8f8f8; -$color-thin-light-grey: #4D5258; +$color-thin-light-grey: #4d5258; $color-join-mark-hovered: #00659c; $color-category-tag: #23a8e0; -$color-ultra-grey-border: #EDEDED; +$color-ultra-grey-border: #ededed; $color-mid-grey: #979797; -$color-vertical-grey: #D1D1D1; -$color-space-grey: #676A6C; -$color-thin-grey-border: #D8D8D8; -$color-published: #6CA100; -$color-review: #F0AB00; -$color-unpublish: #A6A6A6; +$color-vertical-grey: #d1d1d1; +$color-space-grey: #676a6c; +$color-thin-grey-border: #d8d8d8; +$color-published: #6ca100; +$color-review: #f0ab00; +$color-unpublish: #a6a6a6; $color-inactive-dark: #363636; -$color-border-blue: #40A6DA; -$color-dim-grey: #72767B; +$color-border-blue: #40a6da; +$color-dim-grey: #72767b; +$color-primary-text:#141C24; + +$color-background-primary: #ffffff; +$color-brand-primary: #1a75ff; +$color-brand-secondary: #0041cc; +$color-brand-background-primary: #F0F6FF; +$color-neutral-grey: #e4e7ec; +$color-text-secondary: #344051; +$color-text-tertiary: #637083; +$color-error-primary: #F64C4C; +$color-danger-primary: #F64C4C; +$color-dark-blue: #e5eeff; +$color-border-blue: #40a6da; +$color-dim-grey: #72767b; +$color-border-grey: #e4e7ec; +$color-content-3: #344051; +$color-content-05: #637083; +$color-content-07: #ced2da; +$color-content-08: #E4E7EC; +$color-content-09: #F2F4F7; + +$spacing-2: 2px; +$spacing-4: 4px; +$spacing-8: 8px; + +$radius-xxs: 4px; +$radius-s: 8px; + +$sidebar-collapsed-width: 44px; + +:export { + colorContent05: $color-content-05; + colorBrandBackgroundPrimary: $color-brand-background-primary; + colorDangerPrimary: $color-danger-primary; +} \ No newline at end of file diff --git a/sass/widgets/common/IconUploader.scss b/sass/widgets/common/IconUploader.scss index 8b07125be..36d008cca 100644 --- a/sass/widgets/common/IconUploader.scss +++ b/sass/widgets/common/IconUploader.scss @@ -20,4 +20,12 @@ &__description { margin: 10px 0 26px 0; } + + .button-group{ + display: flex; + flex-wrap: wrap; + gap: 8px; + flex: 1; + justify-content: center; + } } diff --git a/sass/widgets/common/WidgetPage.scss b/sass/widgets/common/WidgetPage.scss index e91b4b906..d3335ffe9 100644 --- a/sass/widgets/common/WidgetPage.scss +++ b/sass/widgets/common/WidgetPage.scss @@ -1,14 +1,15 @@ // sass-lint:disable class-name-format no-important .WidgetPage { - height: 100%; min-height: 700px; margin-bottom: 0; - background-color: $color-grey-background; &__header { - padding: 20px; - border-bottom: solid 2px $color-grey-border; - background-color: $color-white; + padding-inline: 20px; + + &__btn-container > div { + display: flex; + width: fit-content; + } } &__body { @@ -35,22 +36,4 @@ margin-left: 216px; padding: 0; } - - & .PageTitle__header { - border: 0; - } - - & .PageTitle__header { - margin-bottom: 0; - } - - & .PageTitle__title { - margin-top: 40px; - margin-bottom: 0; - - & .pull-right { - margin-left: 22px; - float: none !important; - } - } } diff --git a/sass/widgets/config/WidgetConfigPage.scss b/sass/widgets/config/WidgetConfigPage.scss index bb7133572..3ba59ad00 100644 --- a/sass/widgets/config/WidgetConfigPage.scss +++ b/sass/widgets/config/WidgetConfigPage.scss @@ -2,12 +2,11 @@ .WidgetConfigPage { min-height: 100%; margin-bottom: 0; - background-color: $color-grey-background; &__header { - padding: 20px; - border-bottom: solid 2px $color-grey-border; - background-color: $color-white; + &__btn-container { + display: flex; + } } &__body { @@ -30,7 +29,6 @@ & > .container-pf-nav-pf-vertical { height: 100%; - margin-top: 60px; margin-left: 216px; padding: 0; } @@ -44,8 +42,7 @@ } & .PageTitle__title { - margin-top: 40px; - margin-bottom: 0; + padding-inline: 20px; & .pull-right { margin-left: 22px; diff --git a/sass/widgets/config/forms/NavigationBarConfigForm.scss b/sass/widgets/config/forms/NavigationBarConfigForm.scss index 91c4b9938..bc4726aea 100644 --- a/sass/widgets/config/forms/NavigationBarConfigForm.scss +++ b/sass/widgets/config/forms/NavigationBarConfigForm.scss @@ -43,11 +43,19 @@ } .btn-default.active { - border-color: $color-dark-grey; - background-color: $color-dark-grey; color: $color-white; } + .btn-default:hover{ + border: none; + outline: none; + } + + .btn-default:active{ + border: none; + outline: none; + } + select { margin-left: 5px; color: $color-dark-grey; diff --git a/sass/widgets/list/ListWidgetPage.scss b/sass/widgets/list/ListWidgetPage.scss index 5bea29c0d..66eb09b1c 100644 --- a/sass/widgets/list/ListWidgetPage.scss +++ b/sass/widgets/list/ListWidgetPage.scss @@ -1,5 +1,46 @@ .ListWidgetPage { - .ListWidgetPage__add { - margin: 2em 2em 0 0; - } -} + .ListWidgetPage__button-group { + padding-left: 0px; + padding-block: 6px; + display: flex; + justify-content: space-between; + column-gap: 2px; + background-color: #F9FAFB; + border: 1px solid $color-content-09; + + .btn { + padding-inline: 18px; + font-weight: 600; + } + } + + &__toggle-box, + &__box { + display: flex; + gap: 8px; + } + + &__btn-toggle { + color: $color-text-tertiary !important; + font-weight: 500; + } + + &__toggle-box { + .ActiveButton, .btn[disabled] { + background-color:#FFFFFF !important; + box-shadow: 0px 2px 4px 0px rgba(52, 64, 81, 0.12) !important; + color: $color-text-secondary !important; + } + + .CardItemCounter { + cursor: inherit; + } + } + + &__box { + .btn[disabled] { + background-color: $color-content-09 !important; + color: $color-text-secondary !important; + } + } +} \ No newline at end of file diff --git a/sass/widgets/list/WidgetListRow.scss b/sass/widgets/list/WidgetListRow.scss index 0e57c0e1d..5450ed4e4 100644 --- a/sass/widgets/list/WidgetListRow.scss +++ b/sass/widgets/list/WidgetListRow.scss @@ -8,4 +8,25 @@ .WidgetIcon { vertical-align: middle; } + + &__menu-item-container { + display: flex; + align-items: center; + gap: 8px; + padding: 4px 10px; + + a { + display: flex; + align-items: center; + color: $color-text-secondary; + + &:hover { + text-decoration: none; + } + } + + .danger > a { + color: $color-error-primary; + } + } } diff --git a/sass/widgets/list/WidgetListTable.scss b/sass/widgets/list/WidgetListTable.scss index 3c50ff23c..a04f73a47 100644 --- a/sass/widgets/list/WidgetListTable.scss +++ b/sass/widgets/list/WidgetListTable.scss @@ -1,4 +1,66 @@ .WidgetListTable__type { - margin: 0 0 1em 0 ; + margin: 0 0 1em 0; border-bottom: 1px solid $color-pf-black-200; } + +.WidgetListTable { + + .header-container { + display: flex; + align-items: center; + gap: 20px; + } + + .table-bordered { + border: $color-border-grey solid 1px; + } + + .table-header { + background-color: #fff; + border-bottom: 1px solid $color-border-grey; + + td { + border: 1px solid $color-border-grey; + border-left: 0; + border-right: 0; + border-bottom: 0; + } + + .columnResizer { + border-bottom: 1px solid $color-border-grey; + } + + th { + padding: 16px; + border-left: 0; + border-right: 0; + border-bottom: 0; + border-color: $color-border-grey; + } + } + + .table-row { + border-bottom: 1px solid $color-border-grey; + + td { + border: 0 + } + + .colForResize { + border-left: 1px solid transparent; + border-right: 1px solid transparent; + border-bottom: 1px solid $color-border-grey; + } + } + + .table-cell { + vertical-align: middle !important; + padding-inline: 16px !important; + padding-block: 8px !important; + } + + .titles { + display: flex; + align-items: center; + } +} \ No newline at end of file diff --git a/src/api/avatar.js b/src/api/avatar.js new file mode 100644 index 000000000..35b331652 --- /dev/null +++ b/src/api/avatar.js @@ -0,0 +1,39 @@ +import { makeRequest, METHODS } from '@entando/apimanager'; +import { FILE_BROWSER_FILE } from 'test/mocks/fileBrowser'; + +const AVATAR_ENDPOINT = '/api/userProfiles/avatar'; + +export const getAvatar = () => + makeRequest({ + uri: AVATAR_ENDPOINT, + method: METHODS.GET, + mockResponse: FILE_BROWSER_FILE, + useAuthentication: true, + }); + +export const postAvatar = avatar => + makeRequest({ + uri: AVATAR_ENDPOINT, + method: METHODS.POST, + body: avatar, + mockResponse: FILE_BROWSER_FILE, + useAuthentication: true, + }); + +export const updateAvatar = avatar => + makeRequest({ + uri: AVATAR_ENDPOINT, + method: METHODS.PUT, + body: avatar, + mockResponse: FILE_BROWSER_FILE, + useAuthentication: true, + }); + +export const deleteAvatar = () => + makeRequest({ + uri: AVATAR_ENDPOINT, + method: METHODS.DELETE, + mockResponse: FILE_BROWSER_FILE, + useAuthentication: true, + }); + diff --git a/src/api/mfe.js b/src/api/mfe.js index 42edf17ec..24e067f38 100644 --- a/src/api/mfe.js +++ b/src/api/mfe.js @@ -1,13 +1,13 @@ -import { makeRequest, METHODS } from '@entando/apimanager'; -import { LIST_MFE_RESPONSE_OK } from 'test/mocks/mfe'; +import { makeMockRequest, METHODS } from '@entando/apimanager'; +import { LIST_MFE_MENU } from 'test/mocks/mfe'; // eslint-disable-next-line import/prefer-default-export export const getMfeConfigList = (params = '') => ( - makeRequest({ + makeMockRequest({ uri: `/bundles/all/widgets?filters[0].value=app-builder&filters[0].attribute=widgetType&filters[0].operator=eq${params}`, domain: '/digital-exchange', method: METHODS.GET, - mockResponse: LIST_MFE_RESPONSE_OK, + mockResponse: LIST_MFE_MENU, useAuthentication: true, }) ); diff --git a/src/locales/en.js b/src/locales/en.js index 1b28feb5a..9354075a9 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -168,10 +168,12 @@ export default { 'app.zuTitle': 'Zulu title', 'app.save': 'Save', 'app.saveAndContinue': 'Save and continue', - 'app.dontSave': 'Don\'t save', - 'app.confirmCancel': 'Save the current changes? All changes will be lost if you do not save now.', + 'app.dontSave': "Don't save", + 'app.confirmCancel': + 'Save the current changes? All changes will be lost if you do not save now.', 'app.upload': 'Upload', 'app.search': 'Search', + 'app.searchUser': 'Search Username', 'app.back': 'Back', 'app.submit': 'Submit', 'app.fieldsRequired': 'Required fields', @@ -191,16 +193,24 @@ export default { 'app.noOptions': 'No further options', 'app.noMatchOptions': 'No matches found', 'app.add.attribute.code': 'You must insert 3 uppercase characters', - 'app.help.code': 'You can insert uppercase and lowercase letters, numbers and special characters _', - 'app.help.codeWithDash': 'Insert the page code. You can only use alphanumeric characters, and the \'_\' and \'-\' special characters.', - 'app.help.name': 'You can insert a maximum of 50 characters, uppercase and lowercase letters, numbers and special characters.', + 'app.help.code': + 'You can insert uppercase and lowercase letters, numbers and special characters _', + 'app.help.codeWithDash': + "Insert the page code. You can only use alphanumeric characters, and the '_' and '-' special characters.", + 'app.help.name': + 'You can insert a maximum of 50 characters, uppercase and lowercase letters, numbers and special characters.', 'app.all': 'All', 'app.reload': 'Reload', + 'app.content': 'Content', + 'app.contents': 'Contents', + 'app.page': 'Page', 'app.pages': 'Pages', 'app.set': 'Set', 'app.settings': 'Settings', 'app.list': 'List', + 'app.grid': 'Grid', 'app.api': 'API', + 'app.view': 'View', 'app.preview': 'Preview', 'app.restore': 'Restore', 'app.languages': 'Languages', @@ -209,13 +219,18 @@ export default { 'app.mandatory': 'Mandatory', 'app.filterList': 'Can be used as a filter in lists', 'app.ognl.validation': 'OGNL - Validation', - 'app.ognl.validation.help1': 'In this section insert attribute validation. ', - 'app.ognl.validation.help2': 'The OGNL expression must return a boolean value (true or false). In the expression, the object root is the attribute itself. You can access the methods of the attribute without specifying it or using the prefix #attribute.', - 'app.ognl.validation.help3': 'Use the system languages (#langs) map and the associated entity (#entity).', - 'app.ognl.validation.help4': 'For the elements list or composite attributes, access the parent attribute (#parent), and for the elements of list attibutes access the index (#index).', + 'app.ognl.validation.help1': + 'In this section insert attribute validation. ', + 'app.ognl.validation.help2': + 'The OGNL expression must return a boolean value (true or false). In the expression, the object root is the attribute itself. You can access the methods of the attribute without specifying it or using the prefix #attribute.', + 'app.ognl.validation.help3': + 'Use the system languages (#langs) map and the associated entity (#entity).', + 'app.ognl.validation.help4': + 'For the elements list or composite attributes, access the parent attribute (#parent), and for the elements of list attibutes access the index (#index).', 'app.ognl.expression': 'OGNL Expression ', 'app.apply.expression': 'Apply this expression only to a filled attribute', - 'app.ognl.validation.add.message.help': 'Insert a help and compilation error messages, or choose a key to bind them to a system Label.', + 'app.ognl.validation.add.message.help': + 'Insert a help and compilation error messages, or choose a key to bind them to a system Label.', 'app.ognl.message': 'Help message', 'app.help.message.key': 'Key for the help message', 'app.error.message': 'Error message', @@ -231,8 +246,10 @@ export default { 'app.maxLength': 'Maximum length', 'app.regexp': 'Regular expression', 'app.enumeratorStaticItems': 'Elements', - 'app.enumeratorStaticItems.help': 'Insert a configuration like \'lable1,lable2,lable3\'', - 'app.enumeratorStaticItemsMap.help': 'Insert a configuration like \'key1=value1,key2=value2,key3=value3\'', + 'app.enumeratorStaticItems.help': + "Insert a configuration like 'lable1,lable2,lable3'", + 'app.enumeratorStaticItemsMap.help': + "Insert a configuration like 'key1=value1,key2=value2,key3=value3'", 'app.enumeratorStaticItemsSeparator': 'Separator', 'app.enumeratorExtractorBean': 'Extractor bean name', 'app.chooseARole': 'Choose a role', @@ -267,7 +284,8 @@ export default { 'app.created': 'The {type} {code} has been created', 'app.updated': 'The {type} {code} has been updated', 'app.deleted': 'The {type} {code} has been deleted', - 'app.updateSettings.success': 'The settings have been updated successfully.', + 'app.updateSettings.success': + 'The settings have been updated successfully.', 'app.timestamp.hours': 'Select hour', 'app.timestamp.minutes': 'Select minute', 'app.timestamp.seconds': 'Select second', @@ -339,7 +357,8 @@ export default { 'menu.apps': 'Apps', 'menu.settings': 'Administration', 'menu.emailConfig': 'Email Configuration', - 'dashboard.cards.noPermission': 'You have no permission to visualize this data', + 'dashboard.cards.noPermission': + 'You have no permission to visualize this data', 'dashboard.uxComponents.mfeWidgets': 'MFEs & Widgets', 'dashboard.uxComponents.pageTemplates': 'Page Templates', 'dashboard.pageStatus': 'Page Status', @@ -363,13 +382,18 @@ export default { 'pageTree.searchForm.title': 'Search for an existing page', 'pageTree.searchForm.code': 'Page Code', 'pageTree.viewPublishedPage': 'View Published Page', - 'pageTreePage.help': 'The TREE PAGES section allows users to manage existing, and add or move pages. Users can also view and expand or collapse the site map and display all main nodes. Users can also perform actions like: mobile or desktop preview, configure, edit, see details, clone or delete pages. Users can also display the state of drafts and see if pages are in the menu list. ', + 'pageTreePage.help': + 'The TREE PAGES section allows users to manage existing, and add or move pages. Users can also view and expand or collapse the site map and display all main nodes. Users can also perform actions like: mobile or desktop preview, configure, edit, see details, clone or delete pages. Users can also display the state of drafts and see if pages are in the menu list. ', 'pageDetails.title': 'Page Details', - 'pageDetails.help': 'The TREE PAGES section allows users to manage existing, and add or move pages. Users can also view and expand or collapse the site map and display all main nodes. Users can also perform actions like: mobile or desktop preview, configure, edit, see details, clone or delete pages. Users can also display the state of drafts and see if pages are in the menu list. ', + 'pageDetails.help': + 'The TREE PAGES section allows users to manage existing, and add or move pages. Users can also view and expand or collapse the site map and display all main nodes. Users can also perform actions like: mobile or desktop preview, configure, edit, see details, clone or delete pages. Users can also display the state of drafts and see if pages are in the menu list. ', 'pageDetails.emptyContent': 'This page does not publish any content.', - 'pageDetails.emptyContentLink': 'There is no content with a link pointing to this page.', - 'validateForm.elements': 'Insert a configuration like \'key1=value1,key2=value2,key3=value3\'', - 'validateForm.element': 'Insert a configuration like \'lable1,lable2,lable3\'', + 'pageDetails.emptyContentLink': + 'There is no content with a link pointing to this page.', + 'validateForm.elements': + "Insert a configuration like 'key1=value1,key2=value2,key3=value3'", + 'validateForm.element': + "Insert a configuration like 'lable1,lable2,lable3'", 'validateForm.element.code': 'Code must be 3 uppercase letters', 'validateForm.required': 'Field required', 'validateForm.maxLength': 'Must be {max} characters or less.', @@ -381,17 +405,28 @@ export default { 'validateForm.email': 'Invalid email address.', 'validateForm.invalidJson': 'Invalid JSON format: {msg}', 'validateForm.alphaNumeric': 'Alphanumeric characters only.', - 'validateForm.widgetCode': '{name} contains invalid characters. Only alphanumeric characters and the underscore are allowed', - 'validateForm.passwordNotMatch': 'Confirm value doesn\'t match with Password value', - 'validateForm.code.max10digits': 'Code contains invalid characters or has reached the maximum. Only 10 or less numeric characters are allowed.', - 'validateForm.code': 'Code contains invalid characters. Only alphanumeric characters and the underscore are allowed.', - 'validateForm.codeWithDash': 'Code contains invalid characters. Only alphanumeric characters and the underscore \'_\' and dash \'-\'are allowed', - 'validateForm.fragmentCode': 'Code contains invalid characters. Only alphanumeric characters, the underscore, and the dash are allowed.', - 'validateForm.widgetJSON.formatInvalid': 'Config UI must be a valid JSON Format', - 'validateForm.widgetJSON.noCustomElement': 'Invalid Configuration: "customElement" property is missing', - 'validateForm.widgetJSON.customElementString': 'Invalid Configuration: "customElement" property must be a string', - 'validateForm.widgetJSON.resourcesInvalid': 'Invalid Configuration: "resources" must be an array - consist of code source location(s) of indicated custom element', - 'validateForm.widgetJSON.resourcesNotString': 'Invalid Configuration: one of the "resources" is not a string. Please indicate all source locations into string-type', + 'validateForm.widgetCode': + '{name} contains invalid characters. Only alphanumeric characters and the underscore are allowed', + 'validateForm.passwordNotMatch': + "Confirm value doesn't match with Password value", + 'validateForm.code.max10digits': + 'Code contains invalid characters or has reached the maximum. Only 10 or less numeric characters are allowed.', + 'validateForm.code': + 'Code contains invalid characters. Only alphanumeric characters and the underscore are allowed.', + 'validateForm.codeWithDash': + "Code contains invalid characters. Only alphanumeric characters and the underscore '_' and dash '-'are allowed", + 'validateForm.fragmentCode': + 'Code contains invalid characters. Only alphanumeric characters, the underscore, and the dash are allowed.', + 'validateForm.widgetJSON.formatInvalid': + 'Config UI must be a valid JSON Format', + 'validateForm.widgetJSON.noCustomElement': + 'Invalid Configuration: "customElement" property is missing', + 'validateForm.widgetJSON.customElementString': + 'Invalid Configuration: "customElement" property must be a string', + 'validateForm.widgetJSON.resourcesInvalid': + 'Invalid Configuration: "resources" must be an array - consist of code source location(s) of indicated custom element', + 'validateForm.widgetJSON.resourcesNotString': + 'Invalid Configuration: one of the "resources" is not a string. Please indicate all source locations into string-type', 'widget.page.create.pageTitle': 'Info', 'widget.page.create.code': 'Code', 'widget.page.create.code.placeholder': 'Code', @@ -402,7 +437,8 @@ export default { 'widget.page.create.icon': 'Icon', 'widget.page.create.parameters': 'Parameters', 'widget.page.create.config': 'Configuration', - 'widget.page.create.readonlyDefaultConfig': 'Make page widget config readonly', + 'widget.page.create.readonlyDefaultConfig': + 'Make page widget config readonly', 'widget.page.tab.customUi': 'Custom UI', 'widget.page.tab.defaultUi': 'Default UI', 'widget.page.edit.pageTitle': 'Edit widget', @@ -410,8 +446,10 @@ export default { 'widget.page.config.loading': 'Loading micro frontend...', 'widget.page.config.error': 'Unable to load widget configuration', 'widget.page.config.goToConfig': 'Go to widget default configuration', - 'widget.page.config.readOnlyMessage': 'This is the default configuration for this widget. Do you want to change it?', - 'widget.icon.description': 'Upload your Icon from the Icon Library or your Computer', + 'widget.page.config.readOnlyMessage': + 'This is the default configuration for this widget. Do you want to change it?', + 'widget.icon.description': + 'Upload your Icon from the Icon Library or your Computer', 'widget.icon.iconLibrary': 'Icon Library', 'widget.icon.upload': 'Upload', 'widget.icon.insert': 'Insert', @@ -434,9 +472,11 @@ export default { 'widget.detail.table.framePosition': 'Frame position', 'widget.detail.table.action.pageConfig': 'Page configuration', 'widget.detail.table.action.pageDetails': 'Page details', - 'widget.help': 'The WIDGET section allows users to manage existing or add new widgets. Widgets are objects used to display information and functionality or services on the pages of an application.', + 'widget.help': + 'The WIDGET section allows users to manage existing or add new widgets. Widgets are objects used to display information and functionality or services on the pages of an application.', 'fragment.list.title': 'UX Fragments', - 'fragment.help': 'The UX FRAGMENTS section allows users to manage existing or add new UX Fragments. UX Fragments are single portions of a front-end interface used in Widgets (including plugins) and Page Templates.', + 'fragment.help': + 'The UX FRAGMENTS section allows users to manage existing or add new UX Fragments. UX Fragments are single portions of a front-end interface used in Widgets (including plugins) and Page Templates.', 'fragment.code': 'Code', 'fragment.code.placeholder': 'Code', 'fragment.tab.guiCode': 'Gui code', @@ -446,11 +486,15 @@ export default { 'fragment.detail.widgetType': 'Widget type', 'fragment.detail.pluginCode': 'Plugin code', 'fragment.detail.title.referencedFragments': 'Referenced UX fragments', - 'fragment.detail.title.referencedPageTemplates': 'Referenced page templates', + 'fragment.detail.title.referencedPageTemplates': + 'Referenced page templates', 'fragment.detail.title.referencedWidgetType': 'Referenced widget types', - 'fragment.detail.emptyReferenceFragments': 'There are no referenced UX fragments', - 'fragment.detail.emptyReferencePageTemplates': 'There are no referenced page templates', - 'fragment.detail.emptyReferenceWidgetTypes': 'There are no referenced widget types', + 'fragment.detail.emptyReferenceFragments': + 'There are no referenced UX fragments', + 'fragment.detail.emptyReferencePageTemplates': + 'There are no referenced page templates', + 'fragment.detail.emptyReferenceWidgetTypes': + 'There are no referenced widget types', 'fragment.form.edit.plugin': 'Plugin', 'fragment.table.widgetType': 'Widget type', 'fragment.table.plugin': 'Plugin', @@ -458,7 +502,8 @@ export default { 'fragment.table.clone': 'Clone {code}', 'fragment.table.details': 'Details for: {code}', 'fragment.form.edit.widgetType': 'Widget type', - 'fragment.settings': 'Enable editing of UX fragment with empty default gui.', + 'fragment.settings': + 'Enable editing of UX fragment with empty default gui.', 'fragment.settings.alert.success': 'The settings have been updated.', 'fragment.settings.alert.error': 'The settings have not been updated.', 'fragment.alert.error.fileExtension': 'This extension is not permitted.', @@ -472,16 +517,21 @@ export default { 'fileBrowser.createFolder': 'Create folder', 'fileBrowser.uploadFiles': 'Upload files', 'fileBrowser.uploadFileComplete': 'Upload file complete', + 'fileBrowser.removeFileComplete': 'Remove file complete', 'fileBrowser.uploadFileError': 'Error uploading file - {errmsg}', 'fileBrowser.downloadFile': 'Download', 'fileBrowser.newFolder': 'New folder name', - 'fileBrowser.createFolderSuccess': 'Folder \'{path}\' successfully created.', - 'fileBrowser.createFolderError': 'An error has occurred during the creation of the folder \'{path}\'.', - 'fileBrowser.deleteFolderSuccess': 'Folder \'{path}\' successfully deleted.', - 'fileBrowser.deleteFolderError': 'An error has occurred during deletion of the folder \'{path}\'.', - 'fileBrowser.deleteFileSuccess': 'File \'{path}\' successfully deleted.', - 'fileBrowser.deleteFileError': 'An error has occurred during deletion of the file \'{path}\'.', - 'fileBrowser.help': 'The file browser section lets system administrators browse the file system folders.', + 'fileBrowser.createFolderSuccess': "Folder '{path}' successfully created.", + 'fileBrowser.createFolderError': + "An error has occurred during the creation of the folder '{path}'.", + 'fileBrowser.deleteFolderSuccess': "Folder '{path}' successfully deleted.", + 'fileBrowser.deleteFolderError': + "An error has occurred during deletion of the folder '{path}'.", + 'fileBrowser.deleteFileSuccess': "File '{path}' successfully deleted.", + 'fileBrowser.deleteFileError': + "An error has occurred during deletion of the file '{path}'.", + 'fileBrowser.help': + 'The file browser section lets system administrators browse the file system folders.', 'fileBrowser.textFile.placeholder': 'file content here...', 'fileBrowser.textFile.content': 'Content', 'pages.pageForm.info': 'Info', @@ -489,9 +539,11 @@ export default { 'pages.pageForm.pageGroups': 'Page groups', 'pages.pageForm.settings': 'Settings', 'pages.pageForm.ownerGroup': 'Owner group', - 'pages.pageForm.ownerGroupHelp': 'You must set the owner group to define what kind of people (edited in Settings) are able to see this page.', + 'pages.pageForm.ownerGroupHelp': + 'You must set the owner group to define what kind of people (edited in Settings) are able to see this page.', 'pages.pageForm.joinGroup': 'Join group', - 'pages.pageForm.codeHelp': 'Insert the page code. You can only use alphanumeric characters, and the \'_\' and \'-\' special characters.', + 'pages.pageForm.codeHelp': + "Insert the page code. You can only use alphanumeric characters, and the '_' and '-' special characters.", 'pages.pageForm.pagePlacement': 'Select page placement', 'pages.pageForm.pageTemplate': 'Page Template', 'pages.pageForm.pageTemplateHelp': 'Select a page template', @@ -502,12 +554,15 @@ export default { 'pages.pageForm.seo': 'SEO', 'pages.pageForm.seoHelp': 'Activate SEO on page', 'pages.pageForm.charset': 'Charset', - 'pages.pageForm.charsetHelp': 'Interprets a sequence of bytes as representation of characters. The default is set to the machine in use.', + 'pages.pageForm.charsetHelp': + 'Interprets a sequence of bytes as representation of characters. The default is set to the machine in use.', 'pages.pageForm.mimeType': 'MimeType', - 'pages.pageForm.mimeTypeHelp': 'Identifies the type of information (imagine, text..) that Entando gives back to the requesting browser.', + 'pages.pageForm.mimeTypeHelp': + 'Identifies the type of information (imagine, text..) that Entando gives back to the requesting browser.', 'pages.pageForm.saveAndConfigure': 'Save and Design', 'pages.pageForm.seoFriendlyCode': 'SEO-friendly Code', - 'pages.pageForm.useExtDescSearch': 'When available, use extra description in search', + 'pages.pageForm.useExtDescSearch': + 'When available, use extra description in search', 'pages.seoDescr': 'SEO: When available, use extra titles.', 'pages.noPageFound': 'No pages found.', 'pages.status.published': 'Published', @@ -522,8 +577,10 @@ export default { 'pages.designer.tabPageTree': 'Page Tree', 'pages.designer.searchWidgetLabel': 'Search Widgets', 'pages.fullPath': 'Full Path', - 'pageSettings.help': 'The PAGE SETTING section allows the user to specify attributes and conditions for pages and define general page settings.', - 'pageSettings.status.published': 'The updates to page {page} are online now.', + 'pageSettings.help': + 'The PAGE SETTING section allows the user to specify attributes and conditions for pages and define general page settings.', + 'pageSettings.status.published': + 'The updates to page {page} are online now.', 'pageSettings.status.unpublished': 'The page {page} is offline now.', 'pageSettings.input.homepage': 'Home Page', 'pageSettings.input.404': 'Page for: 404 - Page not found', @@ -535,25 +592,33 @@ export default { 'pageSettings.input.baseURL.static': 'Static', 'pageSettings.input.appendBaseURL': 'Append context name on BaseURL', 'pageSettings.input.jsession': 'Use JSESSIONID', - 'pageSettings.input.languageBrowser': 'Home page localization is selected by the requesting browser', + 'pageSettings.input.languageBrowser': + 'Home page localization is selected by the requesting browser', 'pageSettings.input.pageTreeStyle': 'Choose the style of the page tree', 'pageSettings.input.pageTreeStyle.classic': 'Classic', 'pageSettings.input.pageTreeStyle.demand': 'Load nodes on demand', 'pageSettings.input.pageTreeStyle.url': 'URL style', 'pageSettings.input.pageTreeStyle.breadcrumbs': 'Breadcrumbs', - 'pageSettings.baseUrl.help': 'The URLs are produced from the BASE URL defined in the context file (es.: www.entando.com/ site/ en/ pagecode.page). URLs are RELEATIVE when the URL omits the BASE URL (es.: /site /en / pagecode.page). BUILT BY HTTP REQUEST PARAMETERS when the URL is generated from the request parameter generated by the preview request. STATIC when the generated URL is inserted in the BASE URL defined by the context file ( es.: www.entando.com/ site/ en/ pagecode.page)', - 'pageSettings.jsession.help': 'Is a security requirement. Avoiding the JSESSIONID will insert the generated link from the site. You must have cookies activted.', - 'pageSettings.appendBaseUrl.help': 'Add the context name to the BASE URL (es.: /site/) (unused with static BaseURL).', + 'pageSettings.baseUrl.help': + 'The URLs are produced from the BASE URL defined in the context file (es.: www.entando.com/ site/ en/ pagecode.page). URLs are RELEATIVE when the URL omits the BASE URL (es.: /site /en / pagecode.page). BUILT BY HTTP REQUEST PARAMETERS when the URL is generated from the request parameter generated by the preview request. STATIC when the generated URL is inserted in the BASE URL defined by the context file ( es.: www.entando.com/ site/ en/ pagecode.page)', + 'pageSettings.jsession.help': + 'Is a security requirement. Avoiding the JSESSIONID will insert the generated link from the site. You must have cookies activted.', + 'pageSettings.appendBaseUrl.help': + 'Add the context name to the BASE URL (es.: /site/) (unused with static BaseURL).', 'pageSettings.success': 'Page Settings have been updated.', - 'dataModel.help': 'The DATA MODELS section allows the administrator to add or edit content data. The Entando formatting engine, based on models, is used to present content (or a portion of it) to users. Content data use Velocity templates and are easily managed from the administration Interface.', + 'dataModel.help': + 'The DATA MODELS section allows the administrator to add or edit content data. The Entando formatting engine, based on models, is used to present content (or a portion of it) to users. Content data use Velocity templates and are easily managed from the administration Interface.', 'dataModel.type': 'Type', 'dataModel.stylesheet': 'Style Sheet', 'dataModel.model': 'Model', - 'dataModel.deleteDataModelSuccess': 'Data model \'{id}\' successfully deleted', - 'dataModel.deleteDataModelError': 'An error has occurred during deletion of the data model \'{id}\'', + 'dataModel.deleteDataModelSuccess': + "Data model '{id}' successfully deleted", + 'dataModel.deleteDataModelError': + "An error has occurred during deletion of the data model '{id}'", 'dataModel.help.code': 'You can only insert numeric characters,', 'dataType.list.title': 'Data Type', - 'dataType.help': 'The DATA TYPES section allows users to add or edit data types.', + 'dataType.help': + 'The DATA TYPES section allows users to add or edit data types.', 'dataType.table.status': 'Status', 'dataType.table.status.0': 'Ok. Reload if you want.', 'dataType.table.status.1': 'Reloading. Refresh this page.', @@ -567,7 +632,8 @@ export default { 'profileType.table.status.wip': 'Reloading. Refresh this page.', 'profileType.listEmpty': 'There are no PROFILE TYPES available', 'profileType.list.title': 'Profile Types', - 'profileType.help': 'The PROFILE TYPES section allows users to add or edit user profile types.', + 'profileType.help': + 'The PROFILE TYPES section allows users to add or edit user profile types.', 'ProfileType.type': 'Type', 'ProfileType.created': 'PROFILE TYPE created succesfully', 'ProfileType.refreshed': 'PROFILE TYPE reloaded succesfully', @@ -576,14 +642,19 @@ export default { 'pageConfig.applyDefaultWidget': 'Apply the default widget', 'pageConfig.defaultWidgetApplied': 'Default widget applied', 'pageConfig.onTheFlyPage': 'On-the-fly page', - 'pageTemplate.error.overlapping': 'Frame "{frame1}" and "{frame2}" are overlapping', - 'pageTemplate.error.pos': 'Frame "{frame}" "pos" property differs from its index', - 'pageTemplate.error.sketchX1X2format': 'Frame "{frame}": sketch attributes x1 and x2 must be integers between 0 and 11, with x1 <= x2', - 'pageTemplate.error.sketchY1Y2format': 'Frame "{frame}": sketch attributes y1 and y2 must be positive integers, with y1 <= y2', + 'pageTemplate.error.overlapping': + 'Frame "{frame1}" and "{frame2}" are overlapping', + 'pageTemplate.error.pos': + 'Frame "{frame}" "pos" property differs from its index', + 'pageTemplate.error.sketchX1X2format': + 'Frame "{frame}": sketch attributes x1 and x2 must be integers between 0 and 11, with x1 <= x2', + 'pageTemplate.error.sketchY1Y2format': + 'Frame "{frame}": sketch attributes y1 and y2 must be positive integers, with y1 <= y2', 'pageTemplate.error.framesArray': 'configuration.frames must be an array', 'pageTemplate.error.configuration': 'configuration is a required object', 'user.list.title': 'Users', - 'user.help': 'The USERS section allows users to add and manage users and lists, manage user profiles and authorizations, and assign roles and groups.', + 'user.help': + 'The USERS section allows users to add and manage users and lists, manage user profiles and authorizations, and assign roles and groups.', 'user.table.status.active': 'Active', 'user.table.status.disabled': 'Not active', 'user.table.status.inactive': 'Not active', @@ -608,25 +679,34 @@ export default { 'user.profileType': 'Profile Type', 'user.status': 'Status', 'user.searchForm.users': 'Users', - 'user.username.help': 'You can insert at least 4 - max 80 characters, lowercase letters, including numbers, \'.\' and \'_\' special characters.', - 'user.password.help': 'You can insert at least 8 - max 20 characters uppercase and lowercase letters, including numbers, \'.\' and \'_\' special characters. ', - 'user.validate.text': 'Contains invalid characters. You can use only alphanumeric characters, the dot \'.\' and the underscore \'_\'.', + 'user.username.help': + "You can insert at least 4 - max 80 characters, lowercase letters, including numbers, '.' and '_' special characters.", + 'user.password.help': + "You can insert at least 8 - max 20 characters uppercase and lowercase letters, including numbers, '.' and '_' special characters. ", + 'user.validate.text': + "Contains invalid characters. You can use only alphanumeric characters, the dot '.' and the underscore '_'.", 'user.registration': 'Registration', 'user.lastLogin': 'Last login', 'user.reset': 'Reset', 'user.lastPasswordChange': 'Last password change', 'user.restrictions.title': 'User restrictions', - 'user.restrictions.help': 'The USER RESTRICTION section allows administrator to manage the expiration date for system users.', + 'user.restrictions.help': + 'The USER RESTRICTION section allows administrator to manage the expiration date for system users.', 'user.restrictions.passwordSection': 'Password Expiration', 'user.restrictions.avatarSection': 'Avatar', 'user.restrictions.form.active': 'Password Always Active', - 'user.restrictions.form.monthsSinceLastLogin': 'Number of months the password is valid.', - 'user.restrictions.form.maxMonths': 'Number of months the password is valid after last access.', - 'user.restrictions.form.gravatar': 'Enable gravatar integration (avatar of users)', - 'user.restrictions.form.monthsSinceLastLogin.error': 'This value must be equal to or less than the previous field', + 'user.restrictions.form.monthsSinceLastLogin': + 'Number of months the password is valid.', + 'user.restrictions.form.maxMonths': + 'Number of months the password is valid after last access.', + 'user.restrictions.form.gravatar': + 'Enable gravatar integration (avatar of users)', + 'user.restrictions.form.monthsSinceLastLogin.error': + 'This value must be equal to or less than the previous field', 'user.restrictions.months': 'month(s)', 'user.restrictions.success': 'User restrictions have been updated', - 'user.myProfile.help': 'The MY PROFILE section allows users to change their password and manage their profile information.', + 'user.myProfile.help': + 'The MY PROFILE section allows users to change their password and manage their profile information.', 'user.myProfile.passwordSection': 'Change your password', 'user.myProfile.accountSection': 'Edit my account', 'user.myProfile.editProfileSection': 'Edit my profile', @@ -644,14 +724,18 @@ export default { 'user.profile.all': 'All', 'user.profile.with': 'User with a profile', 'user.profile.without': 'User without a profile', - 'group.help': 'The GROUPS section allows administrators to manage existing or add new groups.', + 'group.help': + 'The GROUPS section allows administrators to manage existing or add new groups.', 'group.listEmpty': 'There are no Groups available', 'group.name': 'Name', 'group.code': 'Code', - 'group.name.help': 'You can insert max 50 uppercase and lowercase letters, numbers and special characters.', - 'group.code.help': 'You can insert max 20 characters uppercase and lowercase letters, numbers and \'_\' special character.', + 'group.name.help': + 'You can insert max 50 uppercase and lowercase letters, numbers and special characters.', + 'group.code.help': + "You can insert max 20 characters uppercase and lowercase letters, numbers and '_' special character.", 'database.list.add': 'Create a backup', - 'database.help': 'The DATABASE section allows system administrators to create backups and restore from the database. The feature must be enabled.', + 'database.help': + 'The DATABASE section allows system administrators to create backups and restore from the database. The feature must be enabled.', 'database.noDatabaseYet': 'No backups available.', 'database.inProgress': 'Backup in progress', 'database.gotoList': 'Go to backup list', @@ -662,7 +746,8 @@ export default { 'database.dumpDate': 'Dump Date', 'database.datasource': 'Datasource', 'database.datasourceDetails': 'Datasource Details', - 'labelsAndLanguages.help': 'The LABEL & LANGUAGE section allows users to manage labels and localizations. The first language configured in the system is the default language. Labels are used to handle simple semi-static textual information and are not associated with particular objects.', + 'labelsAndLanguages.help': + 'The LABEL & LANGUAGE section allows users to manage labels and localizations. The first language configured in the system is the default language. Labels are used to handle simple semi-static textual information and are not associated with particular objects.', 'label.searchForm.code': 'Search by code', 'label.searchForm.title': 'Search for existing label', 'language.selectLanguage': 'Select Language', @@ -676,11 +761,13 @@ export default { 'modal.confirm.delete': 'Do you really want to delete {code}?', 'modal.confirm.publish': 'Do you really want to publish {code}?', 'modal.confirm.unpublish': 'Do you really want to unpublish {code}?', - 'widgetConfig.help': 'The WIDGET CONFIGURATION section allows users to configure a generic widget for a specific frame of a page.', + 'widgetConfig.help': + 'The WIDGET CONFIGURATION section allows users to configure a generic widget for a specific frame of a page.', 'widgetConfig.internalServlet.widgetName': 'Internal Servlet', 'widgetConfig.internalServlet.parameters': 'Parameters', 'widgetConfig.internalServlet.actionPath': 'actionPath', - 'widgetConfig.internalServlet.actionPath.help': 'Path to an action or to a JSP. You must prepend \'/ExtStr2\' to any Struts2 action path', + 'widgetConfig.internalServlet.actionPath.help': + "Path to an action or to a JSP. You must prepend '/ExtStr2' to any Struts2 action path", 'group.detail.title.users': 'Users', 'group.detail.title.widgetTypes': 'Widget Types', 'group.detail.title.contents': 'Contents', @@ -694,14 +781,18 @@ export default { 'group.action.pageConfiguration': 'Page configuration', 'group.action.manageAuthorization': 'Manage authorizations for', 'group.content.lastEdit': 'Last edit', - 'pageTemplates.help': 'The PAGE TEMPLATES section allows users to manage existing or add new page templates. The Page Template defines the page structure. A page template is characterized by two elements: scheme (the division of the page in smaller areas called frames) and decoration (the look and feel of the page).', - 'pageTemplates.name.help': 'You can insert a max of 50 uppercase or lowercase letters, numbers and special characters.', - 'pageTemplates.code.help': 'You can insert a max of 40 uppercase or lowercase letters, numbers and special characters.', + 'pageTemplates.help': + 'The PAGE TEMPLATES section allows users to manage existing or add new page templates. The Page Template defines the page structure. A page template is characterized by two elements: scheme (the division of the page in smaller areas called frames) and decoration (the look and feel of the page).', + 'pageTemplates.name.help': + 'You can insert a max of 50 uppercase or lowercase letters, numbers and special characters.', + 'pageTemplates.code.help': + 'You can insert a max of 40 uppercase or lowercase letters, numbers and special characters.', 'pageTemplates.jsonConfiguration': 'JSON configuration', 'pageTemplates.template': 'Template', 'pageTemplates.templatePreview': 'Template preview', 'pageTemplates.pluginCode': 'Plugin code', - 'category.help': 'The CATEGORIES section allows users to manage the category tree and create new categories. Categories allow the classification of information; this classification is useful to present aggregated information to final users.', + 'category.help': + 'The CATEGORIES section allows users to manage the category tree and create new categories. Categories allow the classification of information; this classification is useful to present aggregated information to final users.', 'category.tree': 'Categories tree', 'category.settings': 'Categories settings', 'category.treeStyle': 'Choose the style of the Category tree', @@ -709,10 +800,13 @@ export default { 'category.treeType.request': 'Load nodes on demand', 'category.categoryForm.categoryPlacement': 'Tree position', 'DataType.type': 'Type', - 'role.help': 'The ROLES section allows users to create and manage the user roles. Roles allows administrators to grant permissions to various functions within applications to end users.', + 'role.help': + 'The ROLES section allows users to create and manage the user roles. Roles allows administrators to grant permissions to various functions within applications to end users.', 'role.listEmpty': 'There are no ROLES available', - 'role.name.help': 'You can insert a max of 50 uppercase and lowercase letters, numbers and special characters. ', - 'role.code.help': 'You can insert a max of 20 uppercase and lowercase letters, numbers and special characters.', + 'role.name.help': + 'You can insert a max of 50 uppercase and lowercase letters, numbers and special characters. ', + 'role.code.help': + 'You can insert a max of 20 uppercase and lowercase letters, numbers and special characters.', 'role.detail.referencedUsers': 'Referenced users', 'role.detail.noPermissions': 'There are no permissions', 'permission.listEmpty': 'There are no permissions available', @@ -723,17 +817,25 @@ export default { 'reference.jacmsResourceManager': 'Resources with this category', 'reference.DataObjectManager': 'Data objects with this category', 'reference.jpcollaborationIdeaManager': 'Ideas with this category', - 'reference.noReferencejacmsContentManager': 'There is no referenced content', - 'reference.noReferencejacmsResourceManager': 'There are no referenced resources', - 'reference.noReferenceDataObjectManager': 'There are no referenced data objects', - 'reference.noReferencejpcollaborationIdeaManager': 'There are no referenced ideas', + 'reference.noReferencejacmsContentManager': + 'There is no referenced content', + 'reference.noReferencejacmsResourceManager': + 'There are no referenced resources', + 'reference.noReferenceDataObjectManager': + 'There are no referenced data objects', + 'reference.noReferencejpcollaborationIdeaManager': + 'There are no referenced ideas', 'references.referencedPages': 'Referenced pages', 'reloadConfiguration.title': 'Reload configuration', - 'reloadConfiguration.help': 'The RELOAD CONFIGURATION section allows users to reload the system configuration. This operation is necessary after modifying some parameters.', + 'reloadConfiguration.help': + 'The RELOAD CONFIGURATION section allows users to reload the system configuration. This operation is necessary after modifying some parameters.', 'reloadConfiguration.reload.title': 'Reload the configuration', - 'reloadConfiguration.reload.confirm': 'Are you sure you want to reload the configuration?', - 'reloadConfiguration.confirm.success': 'The configuration has been reloaded.', - 'reloadConfiguration.confirm.error': 'Something went wrong while reloading the configuration. Try again in a minute.', + 'reloadConfiguration.reload.confirm': + 'Are you sure you want to reload the configuration?', + 'reloadConfiguration.confirm.success': + 'The configuration has been reloaded.', + 'reloadConfiguration.confirm.error': + 'Something went wrong while reloading the configuration. Try again in a minute.', 'activityStream.newPage': 'created a new page', 'activityStream.editPage': 'edited a new page', 'activityStream.deletePage': 'delete a page', @@ -742,21 +844,27 @@ export default { 'activityStream.modifyPage': 'modified a page', 'activityStream.like': 'Like', 'activityStream.writeComment': 'Write a comment', - 'reference.text': 'Reload the references for these entity types. Number of types to reload: {count}. ', + 'reference.text': + 'Reload the references for these entity types. Number of types to reload: {count}. ', 'reference.reload': 'Click {link} to reload all data types.', 'componentRepository.disabled.title': 'Component Repository is disabled.', - 'componentRepository.disabled.help': 'Can be enabled by setting COMPONENT_REPOSITORY_UI_ENABLED env variable value in your .env file to true.', + 'componentRepository.disabled.help': + 'Can be enabled by setting COMPONENT_REPOSITORY_UI_ENABLED env variable value in your .env file to true.', 'componentRepository.menuButton.title': 'Hub', 'componentRepository.component.list.title': 'Entando Hub', - 'componentRepository.component.help': 'Entando Hub is a repository from which users can install different widgets, components, fragments, page templates, content templates and content types.', - 'componentRepository.sidebar.componentRepositoryFilterTitle': 'Component Repositories', + 'componentRepository.component.help': + 'Entando Hub is a repository from which users can install different widgets, components, fragments, page templates, content templates and content types.', + 'componentRepository.sidebar.componentRepositoryFilterTitle': + 'Component Repositories', 'componentRepository.sidebar.categoryFilterTitle': 'Categories', 'componentRepository.components.latestVersion': 'Latest Version', 'componentRepository.components.notFound': 'No component available', - 'componentRepository.des.notFound': 'No component repository have been registered yet, to add a new component repository click on the gear icon on the top-right corner of this page', + 'componentRepository.des.notFound': + 'No component repository have been registered yet, to add a new component repository click on the gear icon on the top-right corner of this page', 'componentRepository.components.install': 'Install', 'componentRepository.components.update': 'Update', - 'componentRepository.components.installRollback': 'Installation has failed. The install has been rolled back', + 'componentRepository.components.installRollback': + 'Installation has failed. The install has been rolled back', 'componentRepository.components.installing': 'Installing {version}', 'componentRepository.components.uninstalling': 'Uninstalling {version}', 'componentRepository.components.failedInstall': 'Installation Failure', @@ -765,20 +873,28 @@ export default { 'componentRepository.components.recheck': 'Re-check', 'componentRepository.components.retry': 'Retry', 'componentRepository.components.inprogress': 'In Progress', - 'componentRepository.components.notifyInProgress': 'Installation still in progress. You can check again by refreshing the page.', - 'componentRepository.components.notifyFailedInstall': 'An error has occured during installation.', - 'componentRepository.components.notifyFailedUninstall': 'An error has occured during uninstallation.', + 'componentRepository.components.notifyInProgress': + 'Installation still in progress. You can check again by refreshing the page.', + 'componentRepository.components.notifyFailedInstall': + 'An error has occured during installation.', + 'componentRepository.components.notifyFailedUninstall': + 'An error has occured during uninstallation.', 'componentRepository.components.uninstall': 'Uninstall', - 'componentRepository.components.confirmUninstall': 'Do you really want to uninstall component {name}?', + 'componentRepository.components.confirmUninstall': + 'Do you really want to uninstall component {name}?', 'componentRepository.components.cannotUninstall': 'Cannot Uninstall', 'componentRepository.components.usage': 'Component usage: {usage}', 'componentRepository.components.showInstallPlan': 'Install plan', - 'componentRepository.components.showCustomInstallPlan': 'Custom install plan', - 'componentRepository.components.installPlanFailed': 'Failed to recover the install plan', - 'componentRepository.components.downgradeMessage': "Please be aware that downgrading a bundle to a previous version may result in a loss of features or data. You may wish to review the bundle's release notes before performing a downgrade.", + 'componentRepository.components.showCustomInstallPlan': + 'Custom install plan', + 'componentRepository.components.installPlanFailed': + 'Failed to recover the install plan', + 'componentRepository.components.downgradeMessage': + "Please be aware that downgrading a bundle to a previous version may result in a loss of features or data. You may wish to review the bundle's release notes before performing a downgrade.", 'componentRepository.components.downgrade': 'Downgrade', 'componentRepository.components.conflict': 'Conflict', - 'componentRepository.components.conflictMessage': "It has not been possible to determine if this operation could imply a downgrade. Please be aware that installing an older version may result in a loss of features or data. You may wish to review the bundle's release notes before proceeding.", + 'componentRepository.components.conflictMessage': + "It has not been possible to determine if this operation could imply a downgrade. Please be aware that installing an older version may result in a loss of features or data. You may wish to review the bundle's release notes before proceeding.", 'componentRepository.components.replace': 'Replace', 'componentRepository.components.proceed': 'Do you want to proceed?', 'componentRepository.sidebar.ratingFilter.title': 'Rating', @@ -799,7 +915,8 @@ export default { 'componentRepository.extraFilters.new': 'New', 'componentRepository.extraFilters.installed': 'Installed', 'componentRepository.settings.title': 'Component Repository settings', - 'componentRepository.settings.help': 'In this section it is possible to setup and manage the settings of marketplaces within the Entando Hub.', + 'componentRepository.settings.help': + 'In this section it is possible to setup and manage the settings of marketplaces within the Entando Hub.', 'componentRepository.settings.add': 'Add Component Repository', 'componentRepository.settings.active': 'Active', 'componentRepository.settings.address': 'Address', @@ -841,7 +958,8 @@ export default { 'singlePageSettings.generalSettings': 'General Settings', 'singlePageSettings.pageTitle': 'Page Title', 'singlePageSettings.updateSuccess': 'Page successfully updated', - 'plugins.noPlugins': 'No installed plugins. See available plugins in the Component Repository', + 'plugins.noPlugins': + 'No installed plugins. See available plugins in the Component Repository', 'plugins.installCallToAction': 'Go to Component Repository', 'widgets.configUi': 'Config UI', 'widgets.addWidget': 'Add Widget', @@ -860,10 +978,14 @@ export default { 'app.seo.addMetatagKey': 'Key', 'app.seo.addMetatagType': 'Type', 'app.seo.addMetatagValue': 'Value', - 'app.pages.titleHelp': 'This serves as the title of your page for SEO purposes', - 'app.seo.descriptionHelp': 'The meta description is a fragment of text that summarizes the content of the page', - 'app.seo.keywordsHelp': 'The meta keywords is a fragment of text that indicates the main keywords of the page, comma separated.', - 'app.seo.addMetatagHelp': 'In this section you can add a new metatag (custom or suggested by an internal catalog)', + 'app.pages.titleHelp': + 'This serves as the title of your page for SEO purposes', + 'app.seo.descriptionHelp': + 'The meta description is a fragment of text that summarizes the content of the page', + 'app.seo.keywordsHelp': + 'The meta keywords is a fragment of text that indicates the main keywords of the page, comma separated.', + 'app.seo.addMetatagHelp': + 'In this section you can add a new metatag (custom or suggested by an internal catalog)', 'app.seo.inheritLangLabel': 'Inherit from default lang', 'pagination.firstPage': 'First page', 'pagination.previousPage': 'Previous page', @@ -887,24 +1009,30 @@ export default { 'widget.navigationBar.config.addNewExpression': 'Add a new expression', 'widget.navigationBar.config.none': 'None (not specified)', 'widget.navigationBar.config.allChildren': 'All children of the page', - 'widget.navigationBar.config.fromTheRootToSelected': 'From the root to the selected page', + 'widget.navigationBar.config.fromTheRootToSelected': + 'From the root to the selected page', 'widget.navigationBar.config.subtree': 'Subtree', 'widget.navigationBar.config.noExpressions': 'Set some expressions..', 'widget.update.success': 'Widget has been updated successfully.', 'widget.navigationBar.config.subtreeDepthAbr': 'Subtree depth', 'info.license': 'License', - 'info.license.description': 'The Entando platform is 100% open source and as a whole is licensed under the LGPL v3.0. \n\nA free commercial open source license is available for Entando platform and the Entando Hub for customers with Gold and Platinum subscriptions.\nWith this license, you can freely extend or modify Entando without requiring the contribution of confidential IP back to the open source community.\n\nThe Subscription entitles you to receive support services, intended as maintenance and warranty of the software (bug fixing), for all the products and components subscribed throughout the period of the contract.', + 'info.license.description': + 'The Entando platform is 100% open source and as a whole is licensed under the LGPL v3.0. \n\nA free commercial open source license is available for Entando platform and the Entando Hub for customers with Gold and Platinum subscriptions.\nWith this license, you can freely extend or modify Entando without requiring the contribution of confidential IP back to the open source community.\n\nThe Subscription entitles you to receive support services, intended as maintenance and warranty of the software (bug fixing), for all the products and components subscribed throughout the period of the contract.', 'info.license.type': 'LGPL v3.0 license', 'info.about': 'About', 'info.about.entandoPlatform': 'Entando Platform', - 'info.about.entando': 'Entando is the leading open source Application Composition Platform for Kubernetes. It enables parallel teams to accelerate development and innovation of business capabilities on a modern, cloud-native, and Kubernetes-native stack.', - 'info.about.docs': 'The documentation helps you learn about the Entando Platform and start exploring its features.\n To get started using the Entando Platform, visit', + 'info.about.entando': + 'Entando is the leading open source Application Composition Platform for Kubernetes. It enables parallel teams to accelerate development and innovation of business capabilities on a modern, cloud-native, and Kubernetes-native stack.', + 'info.about.docs': + 'The documentation helps you learn about the Entando Platform and start exploring its features.\n To get started using the Entando Platform, visit', 'info.about.version': 'Version {version}', - 'reference.text.success': 'References must be reloaded whenever a profile is modified.', + 'reference.text.success': + 'References must be reloaded whenever a profile is modified.', 'reference.label.success': 'Everything is fine.', 'reference.status.title': 'Reference status', 'user.table.profileType': 'Profile Type', - 'app.deleteRoleImpossible': 'Role cannot be deleted until it is removed from all the following users', + 'app.deleteRoleImpossible': + 'Role cannot be deleted until it is removed from all the following users', 'app.saveAs': 'Save As', 'menu.widgetClone': 'Clone widget', 'widget.page.clone.pageTitle': 'Clone widget', @@ -912,40 +1040,54 @@ export default { 'user.myProfile.appSettingsSection': 'Preferences', 'user.myProfile.disableContentMenu': 'Disable Content Menu', 'user.myProfile.wizardToggle': 'Welcome Wizard', - 'user.myProfile.wizardToggleHelp': 'Enable or disable Welcome Wizard that guides you through the "Create first application" process', + 'user.myProfile.wizardToggleHelp': + 'Enable or disable Welcome Wizard that guides you through the "Create first application" process', 'user.myProfile.translationWarning': 'Missing Translation Warning', - 'user.myProfile.translationWarningHelp': 'Enable or disable the warning message to remember you to fill the translation fields of a content.', + 'user.myProfile.translationWarningHelp': + 'Enable or disable the warning message to remember you to fill the translation fields of a content.', 'user.myProfile.loadOnPageSelect': 'Load on Page Select', - 'user.myProfile.loadOnPageSelectHelp': 'Loads a page tree page in the page designer upon selecting it.', + 'user.myProfile.loadOnPageSelectHelp': + 'Loads a page tree page in the page designer upon selecting it.', 'user.myProfile.defaultPageOwnerGroup': 'Default Page Owner Group', - 'user.myProfile.defaultPageOwnerGroupHelp': 'Sets the default owner group when creating a page.', + 'user.myProfile.defaultPageOwnerGroupHelp': + 'Sets the default owner group when creating a page.', 'user.myProfile.defaultPageJoinGroups': 'Default Page Join Groups', - 'user.myProfile.defaultPageJoinGroupsHelp': 'Sets the default join groups when creating a page.', + 'user.myProfile.defaultPageJoinGroupsHelp': + 'Sets the default join groups when creating a page.', 'user.myProfile.defaultContentOwnerGroup': 'Default Content Owner Group', - 'user.myProfile.defaultContentOwnerGroupHelp': 'Sets the default owner group when creating a content.', + 'user.myProfile.defaultContentOwnerGroupHelp': + 'Sets the default owner group when creating a content.', 'user.myProfile.defaultContentJoinGroups': 'Default Content Join Groups', - 'user.myProfile.defaultContentJoinGroupsHelp': 'Sets the default join groups when creating a content.', + 'user.myProfile.defaultContentJoinGroupsHelp': + 'Sets the default join groups when creating a content.', 'user.myProfile.defaultWidgetOwnerGroup': 'Default Widget Owner Group', - 'user.myProfile.defaultWidgetOwnerGroupHelp': 'Sets the default owner group when creating a widget or MFE.', + 'user.myProfile.defaultWidgetOwnerGroupHelp': + 'Sets the default owner group when creating a widget or MFE.', 'tour.start.welcome': 'Welcome to Entando', 'tour.start.title': 'Create Your First Application', - 'tour.start.description': 'Use this wizard to create your first page. It will guide you through all the required steps to create and design a page', + 'tour.start.description': + 'Use this wizard to create your first page. It will guide you through all the required steps to create and design a page', 'tour.start.dontShow': 'Don’t show next time', 'tour.step.2.main': 'Create Your First Application', 'tour.step.2.title': 'Entando AppBuilder', - 'tour.step.2.description': 'The AppBuilder is where you\'ll go to create all of your apps using web content, micro frontends, and microservices.', + 'tour.step.2.description': + "The AppBuilder is where you'll go to create all of your apps using web content, micro frontends, and microservices.", 'tour.step.cancel.title': 'Are you sure you want to exit the tutorial?', 'app.next': 'Next', 'tour.step.3.title': 'Create the Home Page', - 'tour.step.3.description': 'The first step that we’ll want to do is to create our home page. Click Pages in the left sidebar.', + 'tour.step.3.description': + 'The first step that we’ll want to do is to create our home page. Click Pages in the left sidebar.', 'tour.step.4.title': 'Page Management', 'tour.step.4.description': 'Next, click Management.', 'tour.step.5.title': 'Create a Page', - 'tour.step.5.description': 'Here, you\'ll see a list of pages that represent the page tree of your site. Click Add to create a new page.', + 'tour.step.5.description': + "Here, you'll see a list of pages that represent the page tree of your site. Click Add to create a new page.", 'tour.step.6.title': 'Enter a Page Title', - 'tour.step.6.description': 'This serves as the title of your page for SEO purposes.', + 'tour.step.6.description': + 'This serves as the title of your page for SEO purposes.', 'tour.step.7.title': 'Enter a Page Code', - 'tour.step.7.description': 'The page code is used to uniquely identify a page, and is also used for search. In our example, we’ll use ‘hello_world_app’ for the page code.', + 'tour.step.7.description': + 'The page code is used to uniquely identify a page, and is also used for search. In our example, we’ll use ‘hello_world_app’ for the page code.', 'tour.step.8.title': 'Choose a place within your site for your page', 'tour.step.8.description': 'Choose a place for your page', 'tour.step.9.title': 'Choose the Owner Group', @@ -953,35 +1095,50 @@ export default { 'tour.step.10.title': 'Choose the Page Template', 'tour.step.10.description': 'Choose the Page Template', 'tour.step.11.title': 'Save and Design', - 'tour.step.11.description': 'Once we save our settings, we can start designing our page.', + 'tour.step.11.description': + 'Once we save our settings, we can start designing our page.', 'tour.step.12.title': 'Add Widgets', - 'tour.step.12.description': 'On the right sidebar, expand the Page menu. Then drag & drop the Logo widget into the dotted grey \'Logo\' section on the page.', + 'tour.step.12.description': + "On the right sidebar, expand the Page menu. Then drag & drop the Logo widget into the dotted grey 'Logo' section on the page.", 'tour.step.13.title': 'Add Widgets', - 'tour.step.13.description': 'Click Next to add pre-configured Navigation Menu widget to the page design for top level horizontal menu', + 'tour.step.13.description': + 'Click Next to add pre-configured Navigation Menu widget to the page design for top level horizontal menu', 'tour.step.14.title': 'Add Widgets', - 'tour.step.14.description': 'On the right sidebar, expand the CMS menu. Then drag & drop the Search Form widget into the dotted grey \'Search Form\' section on the page.', + 'tour.step.14.description': + "On the right sidebar, expand the CMS menu. Then drag & drop the Search Form widget into the dotted grey 'Search Form' section on the page.", 'tour.step.15.title': 'Add Widgets', - 'tour.step.15.description': 'On the right sidebar, expand the System menu. Then drag & drop the Login widget into the dotted grey \'Login\' section on the page.', + 'tour.step.15.description': + "On the right sidebar, expand the System menu. Then drag & drop the Login widget into the dotted grey 'Login' section on the page.", 'tour.step.16.title': 'Add Widgets', - 'tour.step.16.description': 'Click Next to add pre-configured Content widget to the page', + 'tour.step.16.description': + 'Click Next to add pre-configured Content widget to the page', 'tour.step.17.title': 'Add Widgets', - 'tour.step.17.description': 'Click Next to add pre-configured Content List widget to the page', + 'tour.step.17.description': + 'Click Next to add pre-configured Content List widget to the page', 'tour.step.18.title': 'Add Widgets', - 'tour.step.18.description': 'Click Next to add pre-configured Navigation Menu widget to add link for sitemap in the footer', + 'tour.step.18.description': + 'Click Next to add pre-configured Navigation Menu widget to add link for sitemap in the footer', 'tour.step.19.title': 'Preview', - 'tour.step.19.description': 'Click Preview to see what your page will look like before you publish the page.', + 'tour.step.19.description': + 'Click Preview to see what your page will look like before you publish the page.', 'tour.step.20.title': 'Publish', 'tour.step.20.description': 'Click Publish to see your page live.', 'user.wizard.success': 'Wizard has been updated.', - 'app.pages.friendlyCodeHelp': 'URL slug for the page. You can insert a max of 100 characters, lowercase letters, numbers or \'_\' and \'-\' special characters', - 'validateForm.friendlyCode': 'Friendly Code must be lowercase letters, including numbers or \'_\' special character.', - 'validateForm.friendlyCodeWithDash': 'Friendly Code must only be made of lowercase letters, numbers or \'_\' and \'-\' special characters.', - 'validateForm.friendlyCodeUnique': 'Friendly Code must be unique for all languages.', + 'app.pages.friendlyCodeHelp': + "URL slug for the page. You can insert a max of 100 characters, lowercase letters, numbers or '_' and '-' special characters", + 'validateForm.friendlyCode': + "Friendly Code must be lowercase letters, including numbers or '_' special character.", + 'validateForm.friendlyCodeWithDash': + "Friendly Code must only be made of lowercase letters, numbers or '_' and '-' special characters.", + 'validateForm.friendlyCodeUnique': + 'Friendly Code must be unique for all languages.', 'app.startTutorial': 'Start Welcome Wizard', 'emailConfig.smtpServer': 'SMTP Server', 'emailConfig.senderMgmt': 'Sender Management', - 'emailConfig.help': 'The Email Configuration plugin provides basic functionality to send email. This plugin is a prerequisite for all plugins that require email delivery. Administrators must configure the network configuration and create at least one sender profile.', - 'emailConfig.smtpServer.panelMsg': 'Host is mandatory. Port and Timeout if blank, will default to 25 and 10000. Please leave Username and Password blank if the SMTP server does not require authentication.', + 'emailConfig.help': + 'The Email Configuration plugin provides basic functionality to send email. This plugin is a prerequisite for all plugins that require email delivery. Administrators must configure the network configuration and create at least one sender profile.', + 'emailConfig.smtpServer.panelMsg': + 'Host is mandatory. Port and Timeout if blank, will default to 25 and 10000. Please leave Username and Password blank if the SMTP server does not require authentication.', 'emailConfig.smtpServer.generalSettings': 'General Settings', 'emailConfig.smtpServer.active': 'Active', 'emailConfig.smtpServer.debugMode': 'Debug Mode', @@ -1086,15 +1243,18 @@ export default { 'cms.label.date.placeholder': 'dd/mm/yyyy', 'cms.label.presenter.placeholder': 'Press enter to save changes', 'cms.label.modal.confirmdelete': 'Do you really want to delete {code}?', - 'cms.label.modal.confirmDeleteVersion': 'Do you really want to permanently delete version {version}?', - 'cms.label.modal.confirmRestore': 'Do you really want to restore version {version}? By confirming, the Latest Version will be replaced with this one.', + 'cms.label.modal.confirmDeleteVersion': + 'Do you really want to permanently delete version {version}?', + 'cms.label.modal.confirmRestore': + 'Do you really want to restore version {version}? By confirming, the Latest Version will be replaced with this one.', 'cms.label.modal.confirmCancel': 'Do you want to save all changes?', - 'cms.label.dontSave': 'Don\'t save', + 'cms.label.dontSave': "Don't save", 'cms.label.metadata': 'Metadata', 'cms.contents.versioning.author': 'Author', 'cms.versioning.list.lastModify': 'Last Modified', 'cms.label.modal.confirmpublish': 'Do you really want to publish {code}?', - 'cms.label.modal.confirmunpublish': 'Do you really want to unpublish {code}?', + 'cms.label.modal.confirmunpublish': + 'Do you really want to unpublish {code}?', 'cms.label.yes': 'Yes', 'cms.label.no': 'No', 'cms.label.all': 'All', @@ -1129,28 +1289,40 @@ export default { 'cms.contenttemplate.searchFilter.valueName': 'Name', 'cms.contenttemplate.list.contentTypeHeader': 'Content Type', 'cms.contenttemplate.list.contentTypeIdHeader': 'Code', - 'cms.contenttemplate.list.contentTemplateNameHeader': 'Content Template Name', + 'cms.contenttemplate.list.contentTemplateNameHeader': + 'Content Template Name', 'cms.contenttemplate.list.actionsHeader': 'Actions', 'cms.contenttemplate.list.infoDeleted': '{modelname} removed', 'cms.contenttemplate.form.code': 'Code', 'cms.contenttemplate.form.codePlaceholder': 'Code', 'cms.contenttemplate.form.codeHelp': 'You can insert up to 10 numbers', - 'cms.contenttemplate.form.nameHelp': 'You can insert up to 50 characters, including upper or lowercase letters, numbers and special characters', - 'cms.contenttemplate.form.contentTypeHelp': 'Select one existing content type to use for the content template', + 'cms.contenttemplate.form.nameHelp': + 'You can insert up to 50 characters, including upper or lowercase letters, numbers and special characters', + 'cms.contenttemplate.form.contentTypeHelp': + 'Select one existing content type to use for the content template', 'cms.contenttemplate.form.htmlmodel': 'HTML Model', - 'cms.contenttemplate.form.htmlmodelHelp': 'Defines the HTML content structure using the content elements defined by the given content type.', - 'cms.contenttemplate.form.htmlmodel.statusassist': 'Content assist is ON', - 'cms.contenttemplate.form.htmlmodel.statusattrhelp': 'Help about attributes type is OFF', - 'cms.contenttemplate.form.htmlmodel.statusadminconf': 'To change status, set in the admin configuration section.', + 'cms.contenttemplate.form.htmlmodelHelp': + 'Defines the HTML content structure using the content elements defined by the given content type.', + 'cms.contenttemplate.form.htmlmodel.statusassist': + 'Content assist is ON', + 'cms.contenttemplate.form.htmlmodel.statusattrhelp': + 'Help about attributes type is OFF', + 'cms.contenttemplate.form.htmlmodel.statusadminconf': + 'To change status, set in the admin configuration section.', 'cms.contenttemplate.form.saved': 'Content Template "{modelname}" saved', 'cms.contenttemplate.form.editassistant': 'Inline editing assistant', 'cms.contenttemplate.form.stylesheet': 'Style Sheet', - 'cms.contenttemplate.form.stylesheetHelp': 'Provides a stylesheet file to be used with the HTML model', - 'cms.contenttemplate.form.editassist.dialog': 'Provides an example on how to activate INLINE EDITING for Entando labels

  1. Open a TAG like div p span...
  2. add the class 'editContent' to the TAG. Keep in mind that 'editContentText' class can be used in case of a text-area.
  3. then add data-content-id="$content.getId()"
  4. then add the attribute ID (TITLE) of the desidered label adding data-attr-id="TITLE" and close the tag with >. Please be careful when writing the attribute ID as it is case sensitive and it must match the label attribute in the next step
  5. finally add the label of the desidered attribute that will be rendered on screen writing $content.TITLE.text.
  6. Close the TAG (div p span ...) opened at the very beginning.
Result should look like this:

OPEN TAG class="editContent" data-content-id="$content.getId()" data-attr-id="TITLE">
$content.TITLE.text
CLOSE TAG', - 'cms.contenttemplate.form.presscontext': '(press ctrl + space to open content assist menu)', - 'cms.contenttemplate.delete.messageprompt': 'Are you sure you want to remove {id} ({descr})?', + 'cms.contenttemplate.form.stylesheetHelp': + 'Provides a stylesheet file to be used with the HTML model', + 'cms.contenttemplate.form.editassist.dialog': + 'Provides an example on how to activate INLINE EDITING for Entando labels

  1. Open a TAG like div p span...
  2. add the class 'editContent' to the TAG. Keep in mind that 'editContentText' class can be used in case of a text-area.
  3. then add data-content-id="$content.getId()"
  4. then add the attribute ID (TITLE) of the desidered label adding data-attr-id="TITLE" and close the tag with >. Please be careful when writing the attribute ID as it is case sensitive and it must match the label attribute in the next step
  5. finally add the label of the desidered attribute that will be rendered on screen writing $content.TITLE.text.
  6. Close the TAG (div p span ...) opened at the very beginning.
Result should look like this:

OPEN TAG class="editContent" data-content-id="$content.getId()" data-attr-id="TITLE">
$content.TITLE.text
CLOSE TAG', + 'cms.contenttemplate.form.presscontext': + '(press ctrl + space to open content assist menu)', + 'cms.contenttemplate.delete.messageprompt': + 'Are you sure you want to remove {id} ({descr})?', 'cms.contenttype.title': 'Content Types', - 'cms.contenttype.titletip': 'The Content Types section allows the administrator to add or edit content types.', + 'cms.contenttype.titletip': + 'The Content Types section allows the administrator to add or edit content types.', 'cms.contenttype.add.label': 'Add Content Type', 'cms.contenttype.edit.label': 'Edit Content Type', 'cms.contenttype.list.contentTypeNameHeader': 'Name', @@ -1161,16 +1333,21 @@ export default { 'cms.contenttype.list.status.0': 'Ok. Reload if desired.', 'cms.contenttype.list.status.1': 'Reloading. Refresh this page.', 'cms.contenttype.list.status.2': 'Stale status, please reload.', - 'cms.contenttype.reference.text': 'Reload the references for these entity types: {types}. Number of types to reload: {count}. ', - 'cms.contenttype.reference.reload': 'Click {link} to reload all content types.', + 'cms.contenttype.reference.text': + 'Reload the references for these entity types: {types}. Number of types to reload: {count}. ', + 'cms.contenttype.reference.reload': + 'Click {link} to reload all content types.', 'cms.contenttype.attributes.label': 'Attributes', - 'cms.contentType.helpattributes.label': 'The content types section allows the administrator to add or edited selected content type attributes.', + 'cms.contentType.helpattributes.label': + 'The content types section allows the administrator to add or edited selected content type attributes.', 'cms.contenttype.datatype.label': 'Type', 'cms.contenttype.datatype.code.label': 'Code', 'cms.contenttype.form.type': 'Type', 'cms.contenttype.form.code': 'Code', - 'cms.contenttype.form.codeHelp': 'Insert characters, uppercase or lowercase letters, numbers and special characters _', - 'cms.contenttype.attribute.codeHelp': 'You must insert 3 uppercase characters', + 'cms.contenttype.form.codeHelp': + 'Insert characters, uppercase or lowercase letters, numbers and special characters _', + 'cms.contenttype.attribute.codeHelp': + 'You must insert 3 uppercase characters', 'cms.contenttype.attribute.label.listOf': 'List of', 'cms.contenttype.form.name': 'Name', 'cms.contenttype.form.role': 'Role', @@ -1179,25 +1356,35 @@ export default { 'cms.contenttype.form.filter': 'Filter', 'cms.contenttype.form.actions': 'Actions', 'cms.contenttype.form.filterList': 'Can be used as a filter in lists', - 'cms.contenttype.form.metadata.defaultContentTemplate': 'Default content template', - 'cms.contenttype.form.metadata.defaultContentTemplateLists': 'Default content template for lists', + 'cms.contenttype.form.metadata.defaultContentTemplate': + 'Default content template', + 'cms.contenttype.form.metadata.defaultContentTemplateLists': + 'Default content template for lists', 'cms.contenttype.form.metadata.viewPage': 'Page for on-the-fly publishing', 'cms.contenttype.alert.created': 'Content type created successfully', 'cms.contenttype.attribute.add.title': 'Add Content Type Attribute', 'cms.contenttype.attribute.edit.title': 'Edit Content Type Attribute', 'cms.contenttype.enumeratorStaticItems': 'Elements', - 'cms.contenttype.enumeratorStaticItems.help': 'Insert a configuration like "label1,label2,label3"', - 'cms.contenttype.enumeratorStaticItemsMap.help': 'Insert a configuration like "key1=value1,key2=value2,key3=value3"', + 'cms.contenttype.enumeratorStaticItems.help': + 'Insert a configuration like "label1,label2,label3"', + 'cms.contenttype.enumeratorStaticItemsMap.help': + 'Insert a configuration like "key1=value1,key2=value2,key3=value3"', 'cms.contenttype.enumeratorStaticItemsSeparator': 'Separator', 'cms.contenttype.enumeratorExtractorBean': 'Extractor bean name', 'cms.contenttype.ognl.validation': 'OGNL - Validation', - 'cms.contenttype.ognl.validation.help1': 'In this section, insert the attribute validation. ', - 'cms.contenttype.ognl.validation.help2': 'The OGNL expression must return a boolean value (true or false). In the expression, the object root is the attribute itself. You can access the methods of the attribute without specifying it or using the prefix #attribute.', - 'cms.contenttype.ognl.validation.help3': 'Use the map of the system languages (#langs) and the associated entity (#entity).', - 'cms.contenttype.ognl.validation.help4': 'For the elements list or composite attributes, access the parent attribute (#parent) and for the elements list attibutes use the index (#index).', + 'cms.contenttype.ognl.validation.help1': + 'In this section, insert the attribute validation. ', + 'cms.contenttype.ognl.validation.help2': + 'The OGNL expression must return a boolean value (true or false). In the expression, the object root is the attribute itself. You can access the methods of the attribute without specifying it or using the prefix #attribute.', + 'cms.contenttype.ognl.validation.help3': + 'Use the map of the system languages (#langs) and the associated entity (#entity).', + 'cms.contenttype.ognl.validation.help4': + 'For the elements list or composite attributes, access the parent attribute (#parent) and for the elements list attibutes use the index (#index).', 'cms.contenttype.ognl.expression': 'OGNL Expression ', - 'cms.contenttype.apply.expression': 'Apply this expression only to a filled attribute', - 'cms.contenttype.ognl.validation.add.message.help': 'Insert help and compilation error messages, or choose a key to bind them to a system label.', + 'cms.contenttype.apply.expression': + 'Apply this expression only to a filled attribute', + 'cms.contenttype.ognl.validation.add.message.help': + 'Insert help and compilation error messages, or choose a key to bind them to a system label.', 'cms.contenttype.ognl.message': 'Help message', 'cms.contenttype.help.message': 'Help message', 'cms.contenttype.help.message.key': 'Key for the help message', @@ -1205,35 +1392,43 @@ export default { 'cms.contenttype.error.message.key': 'Key for the error message', 'cms.contenttype.labelrole.choose': 'Choose a role', 'cms.contenttype.labelrole.assigned': 'Assigned role', - 'cms.contenttype.labelrole.noroles': 'No roles available: they may have all been assigned.', + 'cms.contenttype.labelrole.noroles': + 'No roles available: they may have all been assigned.', 'cms.contenttype.label.working': 'You are working on attribute:', 'cms.contenttype.label.element.of': 'element of', 'cms.contenttype.label.edit.attribute': 'Edit : attribute - ', 'cms.contenttype.label.edit.Monolist': 'Edit : Monolist', 'cms.contenttype.label.edit.List': 'Edit : List', 'cms.contentsettings.title': 'Content Settings', - 'cms.contentsettings.titletip': 'The CONTENT SETTINGS section allows the administrator to reload content references and indexes, and allows the mapping for some parameters in resource attributes.', + 'cms.contentsettings.titletip': + 'The CONTENT SETTINGS section allows the administrator to reload content references and indexes, and allows the mapping for some parameters in resource attributes.', 'cms.contentsettings.label.reloadreferences': 'Reload the references', 'cms.contentsettings.label.reloadindexes': 'Reload the indexes', 'cms.contentsettings.label.reloadstatus': 'Ready', 'cms.contentsettings.label.reloadstatus.0': 'Ready', 'cms.contentsettings.label.reloadstatus.1': 'Reloading', 'cms.contentsettings.label.reloadstatus.2': 'Error', - 'cms.contentsettings.label.reloadstatus.remark.success': 'The operation was last successful on {date}', - 'cms.contentsettings.label.reloadstatus.remark.failed': 'Last reload in {date}, failed', - 'cms.contentsettings.cropvalueerror': 'Crop value invalid. Format must be "number:number"', + 'cms.contentsettings.label.reloadstatus.remark.success': + 'The operation was last successful on {date}', + 'cms.contentsettings.label.reloadstatus.remark.failed': + 'Last reload in {date}, failed', + 'cms.contentsettings.cropvalueerror': + 'Crop value invalid. Format must be "number:number"', 'cms.contentsettings.cropratios.heading': 'Settings Image Crop Dimensions', 'cms.contentsettings.cropratios.form.title': 'Add crop dimension', 'cms.contentsettings.ratio.added.success': 'Crop ratio added successfully', - 'cms.contentsettings.ratio.deleted.success': 'Crop ratio deleted successfully', - 'cms.contentsettings.ratio.updated.success': 'Crop ratio updated successfully', + 'cms.contentsettings.ratio.deleted.success': + 'Crop ratio deleted successfully', + 'cms.contentsettings.ratio.updated.success': + 'Crop ratio updated successfully', 'cms.contentsettings.label.resourcemap': 'Resource Metadata Mapping', 'cms.contentsettings.form.addmetadata': 'Add Metadata', 'cms.contentsettings.form.key': 'Key', 'cms.contentsettings.form.mapping': 'Mapping', 'cms.contentsettings.form.help': 'In this section, add new metadata', 'cms.contentsettings.form.metadatamapping': 'Metadata Mapping', - 'cms.contentsettings.form.metadatamapping.help': 'Comma delimited list of relationships between the metadata resource and the "{key}" parameter in the association of image resource to content attribute.', + 'cms.contentsettings.form.metadatamapping.help': + 'Comma delimited list of relationships between the metadata resource and the "{key}" parameter in the association of image resource to content attribute.', 'cms.contentsettings.metadata.infoDeleted': '{name} removed', 'cms.new': 'New', 'cms.save': 'Save', @@ -1260,33 +1455,42 @@ export default { 'cms.contents.edit.groups.ownerGroup.button': 'Set group', 'cms.contents.edit.groups.joinGroup.label': 'Join group', 'cms.contents.edit.categories': 'Categories', - 'cms.contents.edit.groups.ownerGroup.tooltip': 'Set the main group now, or some aspects may be unstable.', + 'cms.contents.edit.groups.ownerGroup.tooltip': + 'Set the main group now, or some aspects may be unstable.', 'cms.contents.edit.tip': '* Required Fields', 'cms.contents.edit.contentType.label': 'Content type', 'cms.contents.edit.contentDescription.label': 'Name', - 'cms.contents.edit.contentDescription.tooltip': 'Provide a name or the title will be used, if available.', - 'cms.contents.edit.contentDescription.placeholder': 'Names help users archive, sort, and find contents.', + 'cms.contents.edit.contentDescription.tooltip': + 'Provide a name or the title will be used, if available.', + 'cms.contents.edit.contentDescription.placeholder': + 'Names help users archive, sort, and find contents.', 'cms.contents.edit.version.label': 'Version', 'cms.contents.edit.version.creator': 'created by', 'cms.contents.edit.version.modifier': 'modified by', 'cms.contents.edit.duplicate': 'Copy to all languages', 'cms.contents.edit.label.duplicate': 'Duplicate Contents', - 'cms.contents.edit.label.duplicateHelp': 'Copy and paste the content from this language tab to others', + 'cms.contents.edit.label.duplicateHelp': + 'Copy and paste the content from this language tab to others', 'cms.contents.edit.copytext': 'Copy Text', 'cms.contents.edit.copiedSuccessfully': 'Content copied successfully.', 'cms.stickySave.lastAutoSave': 'Last save was: ', 'cms.content.status.unpublished': 'Unpublished', 'cms.content.status.unpublished.ready': 'Unpublished (ready)', 'cms.content.status.pendingChanges': 'Published, with pending changes', - 'cms.content.status.pendingChanges.publicNotEqualReady': 'Published, with pending changes (ready)', - 'cms.content.status.pendingChanges.publicNotEqualDraft': 'Published, with pending changes', + 'cms.content.status.pendingChanges.publicNotEqualReady': + 'Published, with pending changes (ready)', + 'cms.content.status.pendingChanges.publicNotEqualDraft': + 'Published, with pending changes', 'cms.content.status.published': 'Published', - 'cms.contents.edit.titletip': 'The CONTENT section allows users to manage existing content, access content lists, and add new content. Users can also approve, suspend, or delete content. In Entando, Content is a structured element that represents a set of information built using Content Attributes.', + 'cms.contents.edit.titletip': + 'The CONTENT section allows users to manage existing content, access content lists, and add new content. Users can also approve, suspend, or delete content. In Entando, Content is a structured element that represents a set of information built using Content Attributes.', 'cms.contents.edit.contentAttributes': 'Content Attributes', - 'cms.contents.edit.contentAttributes.language': 'Attributes can only be edited in the default language section.', + 'cms.contents.edit.contentAttributes.language': + 'Attributes can only be edited in the default language section.', 'cms.menu.contents': 'Management', 'cms.contents.list.all': 'All', - 'cms.contents.tip': 'The Content section allows users to manage existing content, access content lists, and add new content. Users can also approve, suspend, or delete content. In Entando, Content is a structured element that represents a set of information built using Content Attributes.', + 'cms.contents.tip': + 'The Content section allows users to manage existing content, access content lists, and add new content. Users can also approve, suspend, or delete content. In Entando, Content is a structured element that represents a set of information built using Content Attributes.', 'cms.contents.quickSearchPlaceHolder': 'Search Content', 'cms.contents.advancedFilters': 'Advanced Filters', 'cms.contents.advancedFilters.invalidDatesRange': 'Invalid date range', @@ -1325,8 +1529,10 @@ export default { 'cms.contents.details': 'Details', 'cms.contents.reloadReferences': 'Reload References', 'cms.contents.categoriesToAdd': 'Select categories to add', - 'cms.contents.chooseJoiningCategories': 'Choose the categories you want to join to the {number} selected content(s)!', - 'cms.contents.joinCategoriesTip': 'This action will change the draft version of the selected content, not the online version. In order to view the changes in the online version, you need to approve the changes.', + 'cms.contents.chooseJoiningCategories': + 'Choose the categories you want to join to the {number} selected content(s)!', + 'cms.contents.joinCategoriesTip': + 'This action will change the draft version of the selected content, not the online version. In order to view the changes in the online version, you need to approve the changes.', 'cms.contents.delete': 'Delete', 'cms.contents.description': 'Name', 'cms.contents.firstEditor': 'Created by', @@ -1347,17 +1553,20 @@ export default { 'cms.contents.selectGroup': 'Select a group', 'cms.contents.selectCategory': 'Select a category', 'cms.contents.selectCategories': 'Select categories', - 'cms.contents.selectedContents': 'You have selected {number} content items, you can', + 'cms.contents.selectedContents': + 'You have selected {number} content items, you can', 'cms.contents.saved': 'Saved', 'cms.contents.modal.filter.title': 'Select one content item', 'cms.contents.modal.missingTranslations.title': 'Missing Translations', - 'cms.contents.modal.missingTranslations.content': 'There are some attributes with missing translations.', + 'cms.contents.modal.missingTranslations.content': + 'There are some attributes with missing translations.', 'cms.linkconfig.title': 'Configure link content', 'cms.linkconfig.attributes.heading': 'Additional attributes', 'cms.linkconfig.pagetree': 'Pages', 'cms.linkconfig.pageSelect': 'Choose a page', 'cms.specialcharModal.title': 'Insert special character', - 'validateForm.name.help': 'You can insert up to a maximum of 50 characters, including uppercase and lowercase letters, numbers and special characters.', + 'validateForm.name.help': + 'You can insert up to a maximum of 50 characters, including uppercase and lowercase letters, numbers and special characters.', 'widget.form.sample': ' Sample form', 'widget.form.linkText': 'Link text', 'widget.form.text': 'Text', @@ -1372,7 +1581,8 @@ export default { 'widget.form.maxElements': 'Max total elements', 'widget.form.default': 'Default', 'widget.form.inclusiveOr': 'Use inclusive filter (OR)', - 'widget.form.inclusiveOrTip': 'When active, filter the contents with an inclusive filter over the selected categories', + 'widget.form.inclusiveOrTip': + 'When active, filter the contents with an inclusive filter over the selected categories', 'widget.form.creationDate': 'Created date', 'widget.form.lastModify': 'Last modified', 'widget.form.asc': 'Ascending', @@ -1383,7 +1593,8 @@ export default { 'widget.form.order': 'Order', 'widget.form.reorder': 'Reorder', 'widget.form.selectFilter': 'Select Filter', - 'widget.form.extraOptionsDescription': 'If desired, customize the title of the widget or add a link to a page.', + 'widget.form.extraOptionsDescription': + 'If desired, customize the title of the widget or add a link to a page.', 'widget.form.filteropt.creationDate': 'by creation date', 'widget.form.filteropt.lastModify': 'by last modified', 'widget.form.filterable.labelPresence': 'Filter by value presence', @@ -1397,9 +1608,12 @@ export default { 'widget.form.filterable.labelDateDelay': 'Delay (days)', 'widget.form.filterable.valuePresence': 'value set', 'widget.form.filterable.valueAbsence': 'value not set', - 'widget.form.filterable.valueOnly': 'which contains: {value}', - 'widget.form.filterable.valuePartial': 'which contains: {value} {partial}', - 'widget.form.filterable.valueDateDelay': ' with delay: {delay} days', + 'widget.form.filterable.valueOnly': + 'which contains: {value}', + 'widget.form.filterable.valuePartial': + 'which contains: {value} {partial}', + 'widget.form.filterable.valueDateDelay': + ' with delay: {delay} days', 'widget.form.filterable.valuePartialPhrase': '(partial matching)', 'widget.form.filterable.valuePartialLabel': 'partial matching', 'widget.form.filterable.valueRangeStart': 'from {start}', @@ -1413,9 +1627,12 @@ export default { 'contentPicker.allStatuses': 'All', 'contentPicker.allTypes': 'All', 'contentPicker.searchPlaceholder': 'Search for content by name or code', - 'widget.warning.nodefaulttemplate.title': 'Default content template not found', - 'widget.warning.nodefaulttemplate.describe': 'There is no default content template for this content type. Either select a specific template or define a default content template for this type.', - 'widget.warning.nodefaulttemplate.multidescribe': 'One of your contents have no default content template (list) of its content type. Please ensure all your content types of your given list has at lease a default content template.', + 'widget.warning.nodefaulttemplate.title': + 'Default content template not found', + 'widget.warning.nodefaulttemplate.describe': + 'There is no default content template for this content type. Either select a specific template or define a default content template for this type.', + 'widget.warning.nodefaulttemplate.multidescribe': + 'One of your contents have no default content template (list) of its content type. Please ensure all your content types of your given list has at lease a default content template.', 'widget.singleContent.config.title': 'Content', 'widget.singleContent.config.content': 'Content', 'widget.singleContent.config.contentTemplate': 'Content template', @@ -1570,13 +1787,15 @@ export default { 'hub.newRegistry': 'New Registry', 'hub.selectRegistry': 'Select Registry', 'hub.localRegistry.title': 'Local Hub', - 'hub.localRegistry.description': 'This is a local hub where all your deployed bundles are appearing as well as ECR components', + 'hub.localRegistry.description': + 'This is a local hub where all your deployed bundles are appearing as well as ECR components', 'hub.newRegistry.name': 'Name', 'hub.newRegistry.url': 'URL', 'hub.newRegistry.apiKey': 'API Key', 'hub.newRegistry.name.error': 'Registry name must be unique', 'hub.newRegistry.url.error': 'Registry URL must be unique', - 'hub.editRegistry.alert': 'Submitting this form will replace the existing API Key. If none will be submitted, the old one will be deleted.', + 'hub.editRegistry.alert': + 'Submitting this form will replace the existing API Key. If none will be submitted, the old one will be deleted.', 'app.filterTypesSelect.organizationName': 'Organization Name', 'app.filterTypesSelect.bundleGroup': 'Bundle Group', 'hub.bundle.installation': 'Bundle Installation', @@ -1602,19 +1821,30 @@ export default { 'componentRepository.categories.category': 'Category', 'componentRepository.categories.group': 'Group', 'componentRepository.components.installedVersion': 'Installed Version', - 'componentRepository.components.genericError': 'An Error has occurred in the Application', - 'page.invalidChildPositionError': 'A page belonging to a group cannot be placed as a child of the root', - 'page.invalidPositionError': 'A page can only be a direct child of a page with the same owner group or free access', - 'app.installFailed': 'An Error occurred and the Bundle could not be installed', - 'app.uninstallFailed': 'An Error occurred and the Bundle could not be uninstalled', + 'componentRepository.components.genericError': + 'An Error has occurred in the Application', + 'page.invalidChildPositionError': + 'A page belonging to a group cannot be placed as a child of the root', + 'page.invalidPositionError': + 'A page can only be a direct child of a page with the same owner group or free access', + 'app.installFailed': + 'An Error occurred and the Bundle could not be installed', + 'app.uninstallFailed': + 'An Error occurred and the Bundle could not be uninstalled', 'app.fetchBundlesFailed': 'Failed to fetch bundles from Registry', 'user.authority.addNew': 'Add new Authorization', - 'componentRepository.refreshBundleVersions': 'Refresh bundle available versions', + 'componentRepository.refreshBundleVersions': + 'Refresh bundle available versions', 'componentRepository.bundle.installVersionsRefreshed': 'Refreshed', - 'componentRepository.hub.epcInstalledTip': 'To correctly update the EPC menu, please refresh the AppBuilder page on your browser', - 'ecr.componentUninstallError': 'Message error - Is not possible to uninstall the {name}', - 'ecr.componentPartiallyDeleted': 'Some elements of the bundle were deleted manually. To completely uninstall the bundle and clear every internal reference please proceed with uninstallation.', - 'componentRepository.components.elementsUninstalled': 'Elements Uninstalled', - 'componentRepository.components.someNotUninstalled': 'Some components were not uninstalled', + 'componentRepository.hub.epcInstalledTip': + 'To correctly update the EPC menu, please refresh the AppBuilder page on your browser', + 'ecr.componentUninstallError': + 'Message error - Is not possible to uninstall the {name}', + 'ecr.componentPartiallyDeleted': + 'Some elements of the bundle were deleted manually. To completely uninstall the bundle and clear every internal reference please proceed with uninstallation.', + 'componentRepository.components.elementsUninstalled': + 'Elements Uninstalled', + 'componentRepository.components.someNotUninstalled': + 'Some components were not uninstalled', }, }; diff --git a/src/locales/it.js b/src/locales/it.js index 3e0ddd6b6..5ff7e7019 100644 --- a/src/locales/it.js +++ b/src/locales/it.js @@ -171,6 +171,7 @@ export default { 'app.dontSave': 'Non salvare', 'app.upload': 'Upload', 'app.search': 'Cerca', + 'app.searchUser': 'Ricerca utente', 'app.back': 'Indietro', 'app.submit': 'Invia', 'app.fieldsRequired': 'Campi obbligatori', @@ -185,23 +186,33 @@ export default { 'app.actions': 'Azioni', 'app.errors': 'Errori', 'app.cancel': 'Cancella', - 'app.confirmCancel': 'Vuoi salvare le modifiche apportate? Le modifiche andranno perse se non le salvi', + 'app.confirmCancel': + 'Vuoi salvare le modifiche apportate? Le modifiche andranno perse se non le salvi', 'app.search.returned': 'La ricerca ha restituito {value} risultati', - 'app.chooseAnOption': 'Seleziona un\'opzione', + 'app.chooseAnOption': "Seleziona un'opzione", 'app.chooseOptions': 'Scegli le opzioni', 'app.noOptions': 'Senza ulteriori opzioni', 'app.noMatchOptions': 'Nessun risultato trovato', - 'app.add.attribute.code': 'Il codice è valido solo se composto da 3 lettere maiuscole', - 'app.help.code': 'Puoi inserire caratteri, lettere maiuscole e minuscole, numeri, ed il carattere speciale _', - 'app.help.codeWithDash': 'Inserisci il codice di pagina. Puoi inserire solo caratteri alfanumerici, e i caratteri speciali \'_\' e \'-\'.', - 'app.help.name': 'Puoi inserire un massimo di 50 caratteri, lettere maiuscole e minuscole, numeri, ed i caratteri speciali', + 'app.add.attribute.code': + 'Il codice è valido solo se composto da 3 lettere maiuscole', + 'app.help.code': + 'Puoi inserire caratteri, lettere maiuscole e minuscole, numeri, ed il carattere speciale _', + 'app.help.codeWithDash': + "Inserisci il codice di pagina. Puoi inserire solo caratteri alfanumerici, e i caratteri speciali '_' e '-'.", + 'app.help.name': + 'Puoi inserire un massimo di 50 caratteri, lettere maiuscole e minuscole, numeri, ed i caratteri speciali', 'app.all': 'Tutti', 'app.reload': 'Ricarica', + 'app.content': 'Contenuto', + 'app.contents': 'Contenuti', + 'app.page': 'Pagina', 'app.pages': 'Pagine', 'app.set': 'Imposta', 'app.settings': 'Impostazioni', 'app.list': 'Lista', + 'app.grid': 'Griglia', 'app.api': 'API', + 'app.view': 'Vista', 'app.preview': 'Anteprima', 'app.restore': 'Ripristina', 'app.number': 'Numbero', @@ -213,16 +224,22 @@ export default { 'app.mandatory': 'Obbligatorio', 'app.filterList': 'Può essere usato come filtro nelle liste', 'app.ognl.validation': 'Validazione - OGNL', - 'app.ognl.validation.help1': 'In questa sezione puoi inserire le validazioni sull\'Attributo. ', - 'app.ognl.validation.help2': 'L\'Espressione OGNL deve restituire un valore Boolean (true o false). Nella costruzione delle espressioni, l\'oggetto \'root\' è l\'attributo stesso (si può accedere ai metodi dell\'attributo senza specificarlo o tramite il prefisso #attribute).', - 'app.ognl.validation.help3': 'Sono disponibili: la mappa delle lingue del sistema (#langs) e l\'Entità a cui è associato (#entity).', - 'app.ognl.validation.help4': 'Inoltre per gli elementi di una Lista o di un Composito è possibile accedere al padre dell\'attributo (#parent) e per gli elementi di una Lista si ha a disposizione l\'indice (#index).', + 'app.ognl.validation.help1': + "In questa sezione puoi inserire le validazioni sull'Attributo. ", + 'app.ognl.validation.help2': + "L'Espressione OGNL deve restituire un valore Boolean (true o false). Nella costruzione delle espressioni, l'oggetto 'root' è l'attributo stesso (si può accedere ai metodi dell'attributo senza specificarlo o tramite il prefisso #attribute).", + 'app.ognl.validation.help3': + "Sono disponibili: la mappa delle lingue del sistema (#langs) e l'Entità a cui è associato (#entity).", + 'app.ognl.validation.help4': + "Inoltre per gli elementi di una Lista o di un Composito è possibile accedere al padre dell'attributo (#parent) e per gli elementi di una Lista si ha a disposizione l'indice (#index).", 'app.ognl.expression': 'Espressione OGNL ', - 'app.apply.expression': 'Usa l\'espressione solo se l\'attributo è valorizzato', - 'app.ognl.validation.add.message.help': 'Si possono inserire sia un messagio d\'aiuto che un messagio di errore, oppure una chiave per collegarli alle etichette di sistema', - 'app.ognl.message': 'Messaggio d\'aiuto', - 'app.help.message.key': 'Chiave per il messagio d\'aiuto', - 'app.error.message': 'Messaggio d\'errore', + 'app.apply.expression': + "Usa l'espressione solo se l'attributo è valorizzato", + 'app.ognl.validation.add.message.help': + "Si possono inserire sia un messagio d'aiuto che un messagio di errore, oppure una chiave per collegarli alle etichette di sistema", + 'app.ognl.message': "Messaggio d'aiuto", + 'app.help.message.key': "Chiave per il messagio d'aiuto", + 'app.error.message': "Messaggio d'errore", 'app.error.message.key': 'Chiave per il messaggio di errore', 'app.indexable': 'Ricercabile', 'app.attribute': '{mode} attributo', @@ -236,16 +253,19 @@ export default { 'app.enumeratorStaticItems': 'Elementi', 'app.enumeratorStaticItemsSeparator': 'Separatore', 'app.enumeratorExtractorBean': 'Estrattore del bean name', - 'app.enumeratorStaticItems.help': 'Inserisci una configurazione del tipo \'lable1,lable2,lable3\'', - 'app.enumeratorStaticItemsMap.help': 'Inserisci una configurazione del tipo \'key1=value1,key2=value2,key3=value3\'', + 'app.enumeratorStaticItems.help': + "Inserisci una configurazione del tipo 'lable1,lable2,lable3'", + 'app.enumeratorStaticItemsMap.help': + "Inserisci una configurazione del tipo 'key1=value1,key2=value2,key3=value3'", 'app.chooseARole': 'Scegli un ruolo', 'app.assigned.roles': 'Ruolo assegnato', - 'app.no.roles': 'Ruoli non disponibili o potrebbero già essere stati assegnati.', + 'app.no.roles': + 'Ruoli non disponibili o potrebbero già essere stati assegnati.', 'app.from': 'Da', 'app.to': 'A', 'app.equal': 'Uguale a', 'app.date.placeholder': 'gg/mm/anno', - 'app.working': 'Stai lavorando sull\'attributo:', + 'app.working': "Stai lavorando sull'attributo:", 'app.element.of': 'elemento di', 'app.filter': 'Filtro', 'app.move': 'Sposta', @@ -260,14 +280,15 @@ export default { 'app.lastModified': 'Ultima Modifica', 'app.logout': 'Esci', 'app.myProfile': 'Mio Profilo', - 'app.homepage': 'Vai all\'Applicazione', + 'app.homepage': "Vai all'Applicazione", 'app.tableName': 'Nome Tabella', 'app.rows': 'Righe', 'app.created': 'Il {type} {code} è stato creato', 'app.updated': 'Il {type} {code} è stato aggiornato', 'app.deleted': 'Il {type} {code} è stato cancellato', - 'app.updateSettings.success': 'La configurazione è stata aggiornata con successo', - 'app.timestamp.hours': 'Seleziona l\'ora', + 'app.updateSettings.success': + 'La configurazione è stata aggiornata con successo', + 'app.timestamp.hours': "Seleziona l'ora", 'app.timestamp.minutes': 'Seleziona i minuti', 'app.timestamp.seconds': 'Seleziona i secondi', 'app.booleanOptions.true': 'Si', @@ -339,7 +360,8 @@ export default { 'menu.apps': 'App', 'menu.settings': 'Amministrazione', 'menu.emailConfig': 'Configurazione Email', - 'dashboard.cards.noPermission': 'Non hai il permesso di visualizzare questi dati', + 'dashboard.cards.noPermission': + 'Non hai il permesso di visualizzare questi dati', 'dashboard.uxComponents.mfeWidgets': 'MFE & Widget', 'dashboard.uxComponents.pageTemplates': 'Template di Pagina', 'dashboard.pageStatus': 'Stato Pagine', @@ -362,14 +384,19 @@ export default { 'pageTree.action.clear': 'Cancella ricerca', 'pageTree.searchForm.title': 'Cerca una pagina esistente', 'pageTree.searchForm.code': 'Codice Pagine', - 'pageTreePage.help': 'Dalla sezione GESTIONE DELLE PAGINE puoi cercare una pagina esistente, aprire tutto l\'albero instantaneamente , oppure chiuderlo e vedere solo i nodi principali. Puoi aggiungere o spostare una pagina. Compiere una seria di azioni: scegliere la preview ad esempio in modalità desktop o mobile, configurare, modificare, visualizzare i dettagli, clonare la pagina o cancellarla. Inoltre puoi visualizzare lo stato ( se la pagina é online o in bozza ) e se compare come voce del menu.', + 'pageTreePage.help': + "Dalla sezione GESTIONE DELLE PAGINE puoi cercare una pagina esistente, aprire tutto l'albero instantaneamente , oppure chiuderlo e vedere solo i nodi principali. Puoi aggiungere o spostare una pagina. Compiere una seria di azioni: scegliere la preview ad esempio in modalità desktop o mobile, configurare, modificare, visualizzare i dettagli, clonare la pagina o cancellarla. Inoltre puoi visualizzare lo stato ( se la pagina é online o in bozza ) e se compare come voce del menu.", 'pageTree.viewPublishedPage': 'Visualizza la pagina pubblicata', 'pageDetails.title': 'Dettaglio Pagina', - 'pageDetails.help': 'Dalla sezione GESTIONE DELLE PAGINE puoi cercare una pagina esistente, aprire tutto l\'albero instantaneamente , oppure chiuderlo e vedere solo i nodi principali. Puoi aggiungere o spostare una pagina. Compiere una seria di azioni: scegliere la preview ad esempio in modalità desktop o mobile, configurare, modificare, visualizzare i dettagli, clonare la pagina o cancellarla. Inoltre puoi visualizzare lo stato ( se la pagina é online o in bozza ) e se compare come voce del menu.', - 'pageDetails.emptyContent': 'Non è ancora stato pubblicato nessun contenuto.', - 'pageDetails.emptyContentLink': 'Non vi sono contenuti con Link a questa pagina.', - 'validateForm.elements': 'inserire un valore tipo \'key1=value1,key2=value2,key3=value3\'', - 'validateForm.element': 'inserire un valore tipo \'lable1,lable2,lable3\'', + 'pageDetails.help': + "Dalla sezione GESTIONE DELLE PAGINE puoi cercare una pagina esistente, aprire tutto l'albero instantaneamente , oppure chiuderlo e vedere solo i nodi principali. Puoi aggiungere o spostare una pagina. Compiere una seria di azioni: scegliere la preview ad esempio in modalità desktop o mobile, configurare, modificare, visualizzare i dettagli, clonare la pagina o cancellarla. Inoltre puoi visualizzare lo stato ( se la pagina é online o in bozza ) e se compare come voce del menu.", + 'pageDetails.emptyContent': + 'Non è ancora stato pubblicato nessun contenuto.', + 'pageDetails.emptyContentLink': + 'Non vi sono contenuti con Link a questa pagina.', + 'validateForm.elements': + "inserire un valore tipo 'key1=value1,key2=value2,key3=value3'", + 'validateForm.element': "inserire un valore tipo 'lable1,lable2,lable3'", 'validateForm.element.code': 'Il Codice deve essere 3 lettere maiuscole', 'validateForm.required': 'campo obbligatorio', 'validateForm.maxLength': 'deve essere al massimo {max} caratteri', @@ -381,17 +408,28 @@ export default { 'validateForm.email': 'Indirizzo email non valido!', 'validateForm.invalidJson': 'Formato JSON non valido: {msg}', 'validateForm.alphaNumeric': 'Solo caratteri alfanumerici', - 'validateForm.widgetCode': '{name} contiene caratteri non consentiti. Usare solo caratteri alfanumerici o undescore _', - 'validateForm.passwordNotMatch': 'Il valore di Conferma non coincide col valore della Password', - 'validateForm.code.max10digits': 'Il codice contiene caratteri non validi o ha raggiunto i requisiti massimi. Sono ammessi solo 10 o meno caratteri numerici.', - 'validateForm.code': 'Codice contiene caratteri non validi. Usare solo caratteri alfanumerici o l\'undescore \'_\'.', - 'validateForm.codeWithDash': 'Codice contiene caratteri non validi. Usare solo caratteri alfanumerici, l\'undescore \'_\' o il trattino \'-\'.', - 'validateForm.fragmentCode': 'Codice contiene caratteri non validi. Usare solo caratteri alfanumerici, l\'undescore \'_\' o il trattino.', - 'validateForm.widgetJSON.formatInvalid': 'Config UI deve essere un formato JSON valido', - 'validateForm.widgetJSON.noCustomElement': 'Configurazione non valida: manca la proprietà "customElement"', - 'validateForm.widgetJSON.customElementString': 'Configurazione non valida: la proprietà "customElement" deve essere una stringa', - 'validateForm.widgetJSON.resourcesInvalid': 'Configurazione non valida: "risorse" deve essere un array - consiste nella posizione o nelle posizioni di origine del codice dell\'elemento personalizzato indicato', - 'validateForm.widgetJSON.resourcesNotString': 'Configurazione non valida: una delle "risorse" non è una stringa. Si prega di indicare tutte le posizioni di origine in tipo stringa', + 'validateForm.widgetCode': + '{name} contiene caratteri non consentiti. Usare solo caratteri alfanumerici o undescore _', + 'validateForm.passwordNotMatch': + 'Il valore di Conferma non coincide col valore della Password', + 'validateForm.code.max10digits': + 'Il codice contiene caratteri non validi o ha raggiunto i requisiti massimi. Sono ammessi solo 10 o meno caratteri numerici.', + 'validateForm.code': + "Codice contiene caratteri non validi. Usare solo caratteri alfanumerici o l'undescore '_'.", + 'validateForm.codeWithDash': + "Codice contiene caratteri non validi. Usare solo caratteri alfanumerici, l'undescore '_' o il trattino '-'.", + 'validateForm.fragmentCode': + "Codice contiene caratteri non validi. Usare solo caratteri alfanumerici, l'undescore '_' o il trattino.", + 'validateForm.widgetJSON.formatInvalid': + 'Config UI deve essere un formato JSON valido', + 'validateForm.widgetJSON.noCustomElement': + 'Configurazione non valida: manca la proprietà "customElement"', + 'validateForm.widgetJSON.customElementString': + 'Configurazione non valida: la proprietà "customElement" deve essere una stringa', + 'validateForm.widgetJSON.resourcesInvalid': + 'Configurazione non valida: "risorse" deve essere un array - consiste nella posizione o nelle posizioni di origine del codice dell\'elemento personalizzato indicato', + 'validateForm.widgetJSON.resourcesNotString': + 'Configurazione non valida: una delle "risorse" non è una stringa. Si prega di indicare tutte le posizioni di origine in tipo stringa', 'widget.page.create.pageTitle': 'Info', 'widget.page.create.code': 'Codice', 'widget.page.create.code.placeholder': 'Codice', @@ -402,16 +440,20 @@ export default { 'widget.page.create.icon': 'Icona', 'widget.page.create.parameters': 'Parametri', 'widget.page.create.config': 'Impostazioni', - 'widget.page.create.readonlyDefaultConfig': 'rendi in sola lettura la configurazione del widget sulla pagina', + 'widget.page.create.readonlyDefaultConfig': + 'rendi in sola lettura la configurazione del widget sulla pagina', 'widget.page.tab.customUi': 'Custom UI', 'widget.page.tab.defaultUi': 'Default UI', 'widget.page.edit.pageTitle': 'Modifica Widget', 'widget.page.alert.notAvailable': 'Non disponibile', 'widget.page.config.loading': 'Caricamento micro frontend in corso...', - 'widget.page.config.error': 'Impossibile caricare la configurazione del widget', + 'widget.page.config.error': + 'Impossibile caricare la configurazione del widget', 'widget.page.config.goToConfig': 'Vai alla configurazione di default', - 'widget.page.config.readOnlyMessage': 'Questa è la configurazione di default del widget. Vuoi modificarla?', - 'widget.icon.description': 'Carica la tua icona dalla libreria delle icone o dal tuo computer', + 'widget.page.config.readOnlyMessage': + 'Questa è la configurazione di default del widget. Vuoi modificarla?', + 'widget.icon.description': + 'Carica la tua icona dalla libreria delle icone o dal tuo computer', 'widget.icon.iconLibrary': 'Icon Library', 'widget.icon.upload': 'Carica', 'widget.icon.insert': 'Inserisci', @@ -426,7 +468,8 @@ export default { 'widget.list.section.user': 'Utente', 'widget.list.section.custom': 'Custom', 'widget.detail.title': 'Posizione del Widget {widgetDescription}', - 'widget.detail.subtitle': 'Elenco delle pagine e dei dettagli dove è presente il widget', + 'widget.detail.subtitle': + 'Elenco delle pagine e dei dettagli dove è presente il widget', 'widget.detail.table.pageCode': 'Codice pagina', 'widget.detail.table.pagePath': 'Percorso della pagina', 'widget.detail.table.publicVersion': 'Versione pubblicata', @@ -434,9 +477,11 @@ export default { 'widget.detail.table.framePosition': 'Posizionamento', 'widget.detail.table.action.pageConfig': 'Configurazione Pagina', 'widget.detail.table.action.pageDetails': 'Dettaglio Pagina', - 'widget.help': 'Dalla sezione MFE e WIDGET puoi gestire i widget esistenti o crearne di nuovi. I widget sono oggetti utilizzati per visualizzare informazioni e funzionalità o servizi sulle pagine di un\'applicazione.', + 'widget.help': + "Dalla sezione MFE e WIDGET puoi gestire i widget esistenti o crearne di nuovi. I widget sono oggetti utilizzati per visualizzare informazioni e funzionalità o servizi sulle pagine di un'applicazione.", 'fragment.list.title': 'UX Fragment', - 'fragment.help': 'Dalla sezione FRAMMENTO UX puoi gestire i Frammenti UX esistenti o crearne di nuovi. I Frammenti UX sono singole porzioni di interfaccia di front-end utilizzati nei Widget (anche quelli dei plugin) e nei Modelli di pagina .', + 'fragment.help': + 'Dalla sezione FRAMMENTO UX puoi gestire i Frammenti UX esistenti o crearne di nuovi. I Frammenti UX sono singole porzioni di interfaccia di front-end utilizzati nei Widget (anche quelli dei plugin) e nei Modelli di pagina .', 'fragment.code': 'Codice', 'fragment.code.placeholder': 'Codice', 'fragment.tab.guiCode': 'Codice Gui', @@ -446,11 +491,15 @@ export default { 'fragment.detail.widgetType': 'Tipo di Widget', 'fragment.detail.pluginCode': 'Codice Plugin', 'fragment.detail.title.referencedFragments': 'UX Fragment associati', - 'fragment.detail.title.referencedPageTemplates': 'Template di Pagine associati', + 'fragment.detail.title.referencedPageTemplates': + 'Template di Pagine associati', 'fragment.detail.title.referencedWidgetType': 'Tipi di Widget associati', - 'fragment.detail.emptyReferenceFragments': 'Non ci sono UX Fragment associati', - 'fragment.detail.emptyReferencePageTemplates': 'Non ci sono template di pagine associati', - 'fragment.detail.emptyReferenceWidgetTypes': 'Non ci sono tipi widget associati', + 'fragment.detail.emptyReferenceFragments': + 'Non ci sono UX Fragment associati', + 'fragment.detail.emptyReferencePageTemplates': + 'Non ci sono template di pagine associati', + 'fragment.detail.emptyReferenceWidgetTypes': + 'Non ci sono tipi widget associati', 'fragment.table.widgetType': 'Tipo di Widget', 'fragment.table.plugin': 'Plugin', 'fragment.table.edit': 'Modifica {code}', @@ -458,10 +507,12 @@ export default { 'fragment.table.details': 'Dettagli di: {code}', 'fragment.form.edit.plugin': 'Plugin', 'fragment.form.edit.widgetType': 'Tipo di Widget', - 'fragment.settings': 'Abilita la creazione di UX Fragment con default GUI vuota', + 'fragment.settings': + 'Abilita la creazione di UX Fragment con default GUI vuota', 'fragment.settings.alert.success': 'Le impostazioni sono state aggiornate', - 'fragment.settings.alert.error': 'Le impostazioni non sono state aggiornate', - 'fragment.alert.error.fileExtension': 'Estensione del file non e\' permessa', + 'fragment.settings.alert.error': + 'Le impostazioni non sono state aggiornate', + 'fragment.alert.error.fileExtension': "Estensione del file non e' permessa", 'fragment.created': 'UX Fragment creato con successo', 'fragment.updated': 'UX Fragment aggiornato con successo', 'fileBrowser.list.upLink': 'su..', @@ -472,16 +523,22 @@ export default { 'fileBrowser.createFolder': 'Crea cartella', 'fileBrowser.uploadFiles': 'Upload File', 'fileBrowser.uploadFileComplete': 'Upload del file completato', - 'fileBrowser.uploadFileError': 'Errore nell\'upload del file - {errmsg}', + 'fileBrowser.removeFileComplete': 'Rimozione file completata', + 'fileBrowser.uploadFileError': "Errore nell'upload del file - {errmsg}", 'fileBrowser.downloadFile': 'Download', 'fileBrowser.newFolder': 'Nome nuova cartella', - 'fileBrowser.createFolderSuccess': 'Cartella \'{path}\' creata correttamente', - 'fileBrowser.createFolderError': 'Si è verificato un errore durante la creazione della cartella \'{path}\'', - 'fileBrowser.deleteFolderSuccess': 'Cartella \'{path}\' cancellata correttamente', - 'fileBrowser.deleteFolderError': 'Si è verificato un errore durante la cancellazione della cartella \'{path}\'', - 'fileBrowser.deleteFileSuccess': 'File \'{path}\' cancellato correttamente', - 'fileBrowser.deleteFileError': 'Si è verificato un errore durante la cancellazione del file \'{path}\'', - 'fileBrowser.help': 'La sezione BROWSER DI FILE permette di navigare le cartelle del file system.', + 'fileBrowser.createFolderSuccess': "Cartella '{path}' creata correttamente", + 'fileBrowser.createFolderError': + "Si è verificato un errore durante la creazione della cartella '{path}'", + 'fileBrowser.deleteFolderSuccess': + "Cartella '{path}' cancellata correttamente", + 'fileBrowser.deleteFolderError': + "Si è verificato un errore durante la cancellazione della cartella '{path}'", + 'fileBrowser.deleteFileSuccess': "File '{path}' cancellato correttamente", + 'fileBrowser.deleteFileError': + "Si è verificato un errore durante la cancellazione del file '{path}'", + 'fileBrowser.help': + 'La sezione BROWSER DI FILE permette di navigare le cartelle del file system.', 'fileBrowser.textFile.placeholder': 'inserisci il contenuto...', 'fileBrowser.textFile.content': 'Contenuto', 'pages.pageForm.info': 'Info', @@ -489,12 +546,15 @@ export default { 'pages.pageForm.pageGroups': 'Gruppi', 'pages.pageForm.settings': 'Configurazione', 'pages.pageForm.ownerGroup': 'Gruppo Proprietario', - 'pages.pageForm.ownerGroupHelp': 'É necessario impostare il Gruppo Proprietario per definire le persone che hanno il permesso di vedere questa pagina. I Gruppi si creano e gestiscono nell\'area Settings di Entando.', + 'pages.pageForm.ownerGroupHelp': + "É necessario impostare il Gruppo Proprietario per definire le persone che hanno il permesso di vedere questa pagina. I Gruppi si creano e gestiscono nell'area Settings di Entando.", 'pages.pageForm.joinGroup': 'Associa Gruppo', - 'pages.pageForm.codeHelp': 'Inserisci il codice di pagina. Puoi inserire solo caratteri alfanumerici, e i caratteri speciali \'_\' e \'-\'.', + 'pages.pageForm.codeHelp': + "Inserisci il codice di pagina. Puoi inserire solo caratteri alfanumerici, e i caratteri speciali '_' e '-'.", 'pages.pageForm.pagePlacement': 'Posizione della pagina', 'pages.pageForm.pageTemplate': 'Template di Pagina', - 'pages.pageForm.pageTemplateHelp': 'Seleziona un template di pagina da utilizzare', + 'pages.pageForm.pageTemplateHelp': + 'Seleziona un template di pagina da utilizzare', 'pages.pageForm.findTemplate': 'Seleziona un template', 'pages.pageForm.chooseTemplate': 'Scegli un modello di pagina', 'pages.pageForm.displayedInMenu': 'Mostra nel menù', @@ -502,12 +562,15 @@ export default { 'pages.pageForm.seo': 'SEO', 'pages.pageForm.seoHelp': 'Attiva le opzioni SEO nella pagina', 'pages.pageForm.charset': 'Charset', - 'pages.pageForm.charsetHelp': 'Interpreta una sequenza di byte attraverso una rappresentazione di caratteri. Di default si ha quello della macchina in uso', + 'pages.pageForm.charsetHelp': + 'Interpreta una sequenza di byte attraverso una rappresentazione di caratteri. Di default si ha quello della macchina in uso', 'pages.pageForm.mimeType': 'MimeType', - 'pages.pageForm.mimeTypeHelp': 'Identifica il tipo di informazione (immagine, testo...) che Entando deve restituire al browser che le richiede', + 'pages.pageForm.mimeTypeHelp': + 'Identifica il tipo di informazione (immagine, testo...) che Entando deve restituire al browser che le richiede', 'pages.pageForm.saveAndConfigure': 'Salva e vai al Designer', 'pages.pageForm.seoFriendlyCode': 'SEO-friendly Code', - 'pages.pageForm.useExtDescSearch': 'Se disponibile, utilizzare una descrizione aggiuntiva nella ricerca', + 'pages.pageForm.useExtDescSearch': + 'Se disponibile, utilizzare una descrizione aggiuntiva nella ricerca', 'pages.seoDescr': 'SEO: Permetti la sovrascrittura del titolo di Pagina', 'pages.noPageFound': 'Nessuna pagina trovata.', 'pages.status.published': 'Pubblicata', @@ -522,9 +585,12 @@ export default { 'pages.designer.tabPageTree': 'Pagine', 'pages.designer.searchWidgetLabel': 'Cerca Widget', 'pages.fullPath': 'Percorso Completo', - 'pageSettings.help': 'La sezione IMPOSTAZIONE PAGINE consente all\'amministratore di specificare quali pagine devono essere utilizzate per scopi particolari e definire alcune impostazioni generali di pagina.', - 'pageSettings.status.published': 'Le modifiche alla pagina {page} sono state messe online!', - 'pageSettings.status.unpublished': 'La pagina {page} è stata messa offline!', + 'pageSettings.help': + "La sezione IMPOSTAZIONE PAGINE consente all'amministratore di specificare quali pagine devono essere utilizzate per scopi particolari e definire alcune impostazioni generali di pagina.", + 'pageSettings.status.published': + 'Le modifiche alla pagina {page} sono state messe online!', + 'pageSettings.status.unpublished': + 'La pagina {page} è stata messa offline!', 'pageSettings.input.homepage': 'Pagina Iniziale', 'pageSettings.input.404': 'Pagina per: 404 - Pagina non trovata', 'pageSettings.input.500': 'Pagina per: 500 - Errore generico', @@ -535,25 +601,33 @@ export default { 'pageSettings.input.baseURL.static': 'Statico', 'pageSettings.input.appendBaseURL': 'Aggiungi nome contesto a BaseURL', 'pageSettings.input.jsession': 'Usa JSESSIONID', - 'pageSettings.input.languageBrowser': 'Lingua della pagina iniziale da configurazione del browser', - 'pageSettings.input.pageTreeStyle': 'Stile dell\'albero delle Pagine', + 'pageSettings.input.languageBrowser': + 'Lingua della pagina iniziale da configurazione del browser', + 'pageSettings.input.pageTreeStyle': "Stile dell'albero delle Pagine", 'pageSettings.input.pageTreeStyle.classic': 'Classico', 'pageSettings.input.pageTreeStyle.demand': 'Carica i nodi su richiesta', 'pageSettings.input.pageTreeStyle.url': 'Stile degli URL', 'pageSettings.input.pageTreeStyle.breadcrumbs': 'A briciole di pane', - 'pageSettings.baseUrl.help': 'Gli URL vengono generati in base al BASE URL definito nel file di contesto "es. www.entando.com/site/it/codicepagina.page" RELATIVO quando nell\'URL generato viene omesso il BASE URL "es. /site /it / codicepagina,page" COSTRUITO DA PARAMETRI DI HTTP REQUEST quando l\'URL generato dalla request prende il parametro generato dalla richiesta precedente STATICO quando nell\'URL viene inserito il BASE URL definito nel file di contesto "es. www.entando.com/ site /it /codicepagina.page"', - 'pageSettings.jsession.help': 'É un requisito di sicurezza. Evita che venga inserito il JSESSIONID nei link generati dall\'applicazione. É necessario avere i cookie attivati.', - 'pageSettings.appendBaseUrl.help': 'Aggiunge il nome del contesto al BASE URL (es.:/site/) (ininfluente con BASE URL statico)', - 'pageSettings.success': 'L\'Impostazione Pagine è stata aggiornata', - 'dataModel.help': 'Dalla sezione MODELLI DI CONTENUTO l’amministratore può aggiungere nuovi modelli di contenuto o modificare quelli già esistenti. Il modello di contenuto è uno schema di formattazione di uno specifico tipo di contenuto. il Modello di Contenuto è realizzato in modo che il motore di renderizzazione di Entando lo traduca in un frammento di HTML che insieme ad opportuni fogli di stile CSS produrrà il risultato desiderato.', + 'pageSettings.baseUrl.help': + 'Gli URL vengono generati in base al BASE URL definito nel file di contesto "es. www.entando.com/site/it/codicepagina.page" RELATIVO quando nell\'URL generato viene omesso il BASE URL "es. /site /it / codicepagina,page" COSTRUITO DA PARAMETRI DI HTTP REQUEST quando l\'URL generato dalla request prende il parametro generato dalla richiesta precedente STATICO quando nell\'URL viene inserito il BASE URL definito nel file di contesto "es. www.entando.com/ site /it /codicepagina.page"', + 'pageSettings.jsession.help': + "É un requisito di sicurezza. Evita che venga inserito il JSESSIONID nei link generati dall'applicazione. É necessario avere i cookie attivati.", + 'pageSettings.appendBaseUrl.help': + 'Aggiunge il nome del contesto al BASE URL (es.:/site/) (ininfluente con BASE URL statico)', + 'pageSettings.success': "L'Impostazione Pagine è stata aggiornata", + 'dataModel.help': + 'Dalla sezione MODELLI DI CONTENUTO l’amministratore può aggiungere nuovi modelli di contenuto o modificare quelli già esistenti. Il modello di contenuto è uno schema di formattazione di uno specifico tipo di contenuto. il Modello di Contenuto è realizzato in modo che il motore di renderizzazione di Entando lo traduca in un frammento di HTML che insieme ad opportuni fogli di stile CSS produrrà il risultato desiderato.', 'dataModel.type': 'Tipo', 'dataModel.stylesheet': 'Foglio di Stile', 'dataModel.model': 'Modello', - 'dataModel.deleteDataModelSuccess': 'Data Model \'{id}\' cancellato correttamente', - 'dataModel.deleteDataModelError': 'Si è verificato un errore durante la cancellazione del Data Model \'{id}\'', + 'dataModel.deleteDataModelSuccess': + "Data Model '{id}' cancellato correttamente", + 'dataModel.deleteDataModelError': + "Si è verificato un errore durante la cancellazione del Data Model '{id}'", 'dataModel.help.code': 'Puoi inserire solo caratteri numerici', 'dataType.list.title': 'Data Type', - 'dataType.help': 'Dalla sezione DATA TYPE l\'amministratore può creare nuovi tipi di dati o modificare quelli già esistenti.', + 'dataType.help': + "Dalla sezione DATA TYPE l'amministratore può creare nuovi tipi di dati o modificare quelli già esistenti.", 'dataType.table.status': 'Status', 'dataType.table.status.0': 'A posto. Se vuoi, ricarica', 'dataType.table.status.1': 'Ricaricamento in corso. Aggiorna la pagina.', @@ -563,11 +637,14 @@ export default { 'dataType.updated': 'TIPO DI DATI aggiornato correttamente', 'profileType.table.status': 'Status', 'profileType.table.status.ok': 'A posto. Se vuoi, ricarica', - 'profileType.table.status.ko': 'Necessità di un ricaricamento: lancialo ora.', - 'profileType.table.status.wip': 'Ricaricamento in corso. Aggiorna la pagina.', + 'profileType.table.status.ko': + 'Necessità di un ricaricamento: lancialo ora.', + 'profileType.table.status.wip': + 'Ricaricamento in corso. Aggiorna la pagina.', 'profileType.listEmpty': 'Non ci sono TIPI di PROFILO disponibili', 'profileType.list.title': 'Tipi di profilo', - 'profileType.help': 'Dalla sezione TIPI DI PROFILO l\'amministratore può creare nuovi tipi di profilo utenti o modificare quelli già esistenti.', + 'profileType.help': + "Dalla sezione TIPI DI PROFILO l'amministratore può creare nuovi tipi di profilo utenti o modificare quelli già esistenti.", 'ProfileType.type': 'Tipo', 'ProfileType.created': 'TIpo di profilo creato con successo', 'ProfileType.refreshed': 'Tipo di profilo ricaricato con successo', @@ -576,14 +653,21 @@ export default { 'pageConfig.applyDefaultWidget': 'Applica widget di default', 'pageConfig.defaultWidgetApplied': 'Widget di default applicati', 'pageConfig.onTheFlyPage': 'Pagina on-the-fly', - 'pageTemplate.error.overlapping': 'I frame "{frame1}" e "{frame2}" sono sovrapposti', - 'pageTemplate.error.pos': 'La proprietà "pos" del frame "{frame}" è diversa dal suo indice', - 'pageTemplate.error.sketchX1X2format': 'Frame "{frame}": gli attributi di sketch x1 e x2 devono essere numeri interi compresi tra 0 e 11, con x1 <= x2', - 'pageTemplate.error.sketchY1Y2format': 'Frame "{frame}": gli attributi di sketch y1 e y2 devono essere numeri interi positivi, con y1 <= y2', - 'pageTemplate.error.framesArray': 'configuration.frames deve essere un Array', - 'pageTemplate.error.configuration': 'configuration è un campo obbbligatorio, di tipo Object', + 'pageTemplate.error.overlapping': + 'I frame "{frame1}" e "{frame2}" sono sovrapposti', + 'pageTemplate.error.pos': + 'La proprietà "pos" del frame "{frame}" è diversa dal suo indice', + 'pageTemplate.error.sketchX1X2format': + 'Frame "{frame}": gli attributi di sketch x1 e x2 devono essere numeri interi compresi tra 0 e 11, con x1 <= x2', + 'pageTemplate.error.sketchY1Y2format': + 'Frame "{frame}": gli attributi di sketch y1 e y2 devono essere numeri interi positivi, con y1 <= y2', + 'pageTemplate.error.framesArray': + 'configuration.frames deve essere un Array', + 'pageTemplate.error.configuration': + 'configuration è un campo obbbligatorio, di tipo Object', 'user.list.title': 'Utenti', - 'user.help': 'Dalla sezione UTENTI l\'amministratore può accedere alla lista degli utenti, gestirne i profili, le autorizzazioni - assegnando ruoli e gruppi - e aggiungere nuovi utenti.', + 'user.help': + "Dalla sezione UTENTI l'amministratore può accedere alla lista degli utenti, gestirne i profili, le autorizzazioni - assegnando ruoli e gruppi - e aggiungere nuovi utenti.", 'user.table.status.active': 'Attivo', 'user.table.status.disabled': 'Non attivo', 'user.table.status.inactive': 'Non attivo', @@ -608,30 +692,38 @@ export default { 'user.profileType': 'Tipo di Profilo', 'user.status': 'Stato', 'user.searchForm.users': 'Utenti', - 'user.username.help': 'Inserire tra 4 e 80 caratteri, lettere minuscole, numeri \'.\' e \'_\'.', - 'user.password.help': 'Inserire tra 8 e 20 caratteri, lettere maiuscole e minuscole, numeri \'.\' e \'_\'.', - 'user.validate.text': 'Contiene caratteri non consentiti. Usare solo caratteri alfanumerici, il punto \'.\' o l\'undescore \'_\'.', + 'user.username.help': + "Inserire tra 4 e 80 caratteri, lettere minuscole, numeri '.' e '_'.", + 'user.password.help': + "Inserire tra 8 e 20 caratteri, lettere maiuscole e minuscole, numeri '.' e '_'.", + 'user.validate.text': + "Contiene caratteri non consentiti. Usare solo caratteri alfanumerici, il punto '.' o l'undescore '_'.", 'user.registration': 'Registrazione', 'user.lastLogin': 'Ultimo accesso', 'user.reset': 'Reset', 'user.lastPasswordChange': 'Ultimo cambio password', 'user.restrictions.title': 'Restrizione Utenti', - 'user.restrictions.help': 'Dalla sezione RESTRIZIONE UTENTI l\'amministratore può attivare un sistema di scadenza delle utenze.', + 'user.restrictions.help': + "Dalla sezione RESTRIZIONE UTENTI l'amministratore può attivare un sistema di scadenza delle utenze.", 'user.restrictions.passwordSection': 'Validità Password', 'user.restrictions.avatarSection': 'Avatar', 'user.restrictions.form.active': 'Password Sempre Attiva', 'user.restrictions.form.monthsSinceLastLogin': 'La password è attiva per', - 'user.restrictions.form.maxMonths': 'Numero di mesi di validità della password dopo l\'ultimo accesso', + 'user.restrictions.form.maxMonths': + "Numero di mesi di validità della password dopo l'ultimo accesso", 'user.restrictions.form.gravatar': 'Abilita Gravatar (Avatar Utenti)', - 'user.restrictions.form.monthsSinceLastLogin.error': 'Questo valore dev\'essere uguale o minore al precedente', + 'user.restrictions.form.monthsSinceLastLogin.error': + "Questo valore dev'essere uguale o minore al precedente", 'user.restrictions.months': 'mesi', 'user.restrictions.success': 'La Restrizione Utenti è stata aggiornata', - 'user.myProfile.help': 'Dalla sezione MIO PROFILO l\'utente puó modificare la password del proprio account e i dati associati al profilo.', + 'user.myProfile.help': + "Dalla sezione MIO PROFILO l'utente puó modificare la password del proprio account e i dati associati al profilo.", 'user.myProfile.passwordSection': 'Cambia la tua password', 'user.myProfile.accountSection': 'Modifica il mio account', 'user.myProfile.editProfileSection': 'Modifica il mio profilo', 'user.myProfile.uploadImage': 'Carica il tuo profilo immagine', - 'user.myProfile.uploadRestriction': 'Solo immagine (JPG, PNG) max {maxSize}', + 'user.myProfile.uploadRestriction': + 'Solo immagine (JPG, PNG) max {maxSize}', 'user.myProfile.oldPassword': 'Password attuale', 'user.myProfile.newPassword': 'Nuova password', 'user.myProfile.newPasswordConfirm': 'Ripeti la nuova password', @@ -639,19 +731,24 @@ export default { 'user.password.success': 'La password è stata aggiornata', 'userprofile.edit': 'Modifica profilo utente', 'userprofile.edit.success': 'Il profilo utente è stato aggiornato', - 'userpreferences.edit.success': "Le preferenze dell'utente sono state aggiornate", - 'form.select.chooseOne': 'Seleziona un\'opzione', + 'userpreferences.edit.success': + "Le preferenze dell'utente sono state aggiornate", + 'form.select.chooseOne': "Seleziona un'opzione", 'user.profile.all': 'Tutti', 'user.profile.with': 'Utente con un profilo', 'user.profile.without': 'Utente senza profilo', - 'group.help': 'Dalla sezione GRUPPI l\'amministratore può gestire i gruppi esistenti o crearne nuovi. I Gruppi servono a definire dei sottoinsiemi di oggetti e ad autorizzare sottoinsiemi di utenti ad operare su di essi.', + 'group.help': + "Dalla sezione GRUPPI l'amministratore può gestire i gruppi esistenti o crearne nuovi. I Gruppi servono a definire dei sottoinsiemi di oggetti e ad autorizzare sottoinsiemi di utenti ad operare su di essi.", 'group.listEmpty': 'Non ci sono GRUPPI disponibili', 'group.name': 'Nome', 'group.code': 'Codice', - 'group.name.help': 'Puoi inserire massimo 50 caratteri, lettere maiuscole e minuscole, numeri, e caratteri speciali.', - 'group.code.help': 'Puoi inserire massimo 20 caratteri, lettere maiuscole e minuscole, numeri, ed il carattere speciale underscore \'_\'.', + 'group.name.help': + 'Puoi inserire massimo 50 caratteri, lettere maiuscole e minuscole, numeri, e caratteri speciali.', + 'group.code.help': + "Puoi inserire massimo 20 caratteri, lettere maiuscole e minuscole, numeri, ed il carattere speciale underscore '_'.", 'database.list.add': 'Crea un backup', - 'database.help': 'Dalla sezione DATABASE gli amministratori di sistema possono effettuare il backup e il ripristino del database, qualora la funzionalità sia abilitata. È una funzione molto importante che se non eseguita in maniera corretta può comportare la perdita irreversibile di dati.', + 'database.help': + 'Dalla sezione DATABASE gli amministratori di sistema possono effettuare il backup e il ripristino del database, qualora la funzionalità sia abilitata. È una funzione molto importante che se non eseguita in maniera corretta può comportare la perdita irreversibile di dati.', 'database.noDatabaseYet': 'Non ci sono backup disponibili.', 'database.inProgress': 'Backup in corso', 'database.gotoList': 'Vai alla lista dei backup', @@ -665,7 +762,8 @@ export default { 'label.detail.title': 'Etichette', 'labels.code.placeholder': 'codice', 'labels.default.language': 'Lingua Predefinita', - 'labelsAndLanguages.help': 'Dalla sezione ETICHETTE E LINGUE è possibile gestire le lingue e le etichette di sistema. Entando supporta il multilingua, l\'amministratore può aggiungere una nuova lingua. La prima lingua configurata nel sistema è la lingua predefinita. Le etichette sono accessori di Entando, usate principalmente per gestire semplici informazioni testuali semi-statiche, non associate ad oggetti particolari.', + 'labelsAndLanguages.help': + "Dalla sezione ETICHETTE E LINGUE è possibile gestire le lingue e le etichette di sistema. Entando supporta il multilingua, l'amministratore può aggiungere una nuova lingua. La prima lingua configurata nel sistema è la lingua predefinita. Le etichette sono accessori di Entando, usate principalmente per gestire semplici informazioni testuali semi-statiche, non associate ad oggetti particolari.", 'language.selectLanguage': 'Seleziona una lingua', 'language.active.listEmpty': 'Non ci sono LINGUE ATTIVE disponibili', 'language.active.add': 'Lingua attiva aggiunta', @@ -675,12 +773,16 @@ export default { 'modal.confirm.movePage': 'Sei sicuro di voler spostare la pagina {code}?', 'modal.confirm.delete': 'Sei sicuro di voler rimuovere {code}?', 'modal.confirm.publish': 'Sei sicuro di voler pubblicare la pagina {code}?', - 'modal.confirm.unpublish': 'Sei sicuro di voler de-pubblicare la pagina {code}?', - 'widgetConfig.help': 'Dalla sezione CONFIGURA WIDGET puoi configurare il Widget, in una posizione precisa della pagina, attraverso un\' interfaccia guidata.', - 'widgetConfig.internalServlet.widgetName': 'Invocazione di una Servlet Interna', + 'modal.confirm.unpublish': + 'Sei sicuro di voler de-pubblicare la pagina {code}?', + 'widgetConfig.help': + "Dalla sezione CONFIGURA WIDGET puoi configurare il Widget, in una posizione precisa della pagina, attraverso un' interfaccia guidata.", + 'widgetConfig.internalServlet.widgetName': + 'Invocazione di una Servlet Interna', 'widgetConfig.internalServlet.parameters': 'Parametri di Configurazione', 'widgetConfig.internalServlet.actionPath': 'Path action', - 'widgetConfig.internalServlet.actionPath.help': 'Path ad una pagina JSP o ad una action Struts. È necessario anteporre \'/ExtStr2\' in caso di action Struts', + 'widgetConfig.internalServlet.actionPath.help': + "Path ad una pagina JSP o ad una action Struts. È necessario anteporre '/ExtStr2' in caso di action Struts", 'group.detail.title.users': 'Utenti', 'group.detail.title.widgetTypes': 'Tipi di Widget', 'group.detail.title.contents': 'Contenuti', @@ -694,25 +796,32 @@ export default { 'group.action.pageConfiguration': 'Configurazione pagina', 'group.action.manageAuthorization': 'Gestici le autorizzazioni per', 'group.content.lastEdit': 'Ultima modifica', - 'pageTemplates.help': 'Dalla sezione MODELLI DI PAGINA puoi gestire i modelli di pagina esistenti o crearne nuovi. Il modello di pagina definisce la struttura della pagina. All\' interno di un\'applicazione Entando si possono configurare più modelli di pagina . Il modello di pagina determina due aspetti: schema (suddivisione della pagina in zone) e decorazione (aspetto grafico della pagina).', - 'pageTemplates.name.help': 'Puoi inserire massimo 50 caratteri, lettere maiuscole e minuscole, numeri, e caratteri speciali.', - 'pageTemplates.code.help': 'Puoi inserire massimo 40 caratteri, lettere maiuscole e minuscole, numeri, e caratteri speciali.', + 'pageTemplates.help': + "Dalla sezione MODELLI DI PAGINA puoi gestire i modelli di pagina esistenti o crearne nuovi. Il modello di pagina definisce la struttura della pagina. All' interno di un'applicazione Entando si possono configurare più modelli di pagina . Il modello di pagina determina due aspetti: schema (suddivisione della pagina in zone) e decorazione (aspetto grafico della pagina).", + 'pageTemplates.name.help': + 'Puoi inserire massimo 50 caratteri, lettere maiuscole e minuscole, numeri, e caratteri speciali.', + 'pageTemplates.code.help': + 'Puoi inserire massimo 40 caratteri, lettere maiuscole e minuscole, numeri, e caratteri speciali.', 'pageTemplates.jsonConfiguration': 'Configurazione JSON', 'pageTemplates.template': 'Template', 'pageTemplates.templatePreview': 'Anteprima Template', 'pageTemplates.pluginCode': 'Codice plugin', - 'category.help': 'Dalla sezione CATEGORIE è possibile gestire l\'albero delle categorie e creare nuove categorie. Le Categorie costituiscono uno schema di classificazione per Contenuti, Risorse ed altri eventuali oggetti derivanti dai componenti, utile per la ricerca e la selezione delle informazioni da pubblicare.', + 'category.help': + "Dalla sezione CATEGORIE è possibile gestire l'albero delle categorie e creare nuove categorie. Le Categorie costituiscono uno schema di classificazione per Contenuti, Risorse ed altri eventuali oggetti derivanti dai componenti, utile per la ricerca e la selezione delle informazioni da pubblicare.", 'category.tree': 'Albero delle categorie', 'category.settings': 'Configurazione delle categorie', - 'category.treeStyle': 'Scegli lo stile dell\'albero delle categorie', + 'category.treeStyle': "Scegli lo stile dell'albero delle categorie", 'category.treeType.classic': 'Classico', 'category.treeType.request': 'Carica i nodi a richiesta', 'category.categoryForm.categoryPlacement': 'Posizione della categoria', 'DataType.type': 'Type', - 'role.help': 'Dalla sezione RUOLI l\'amministratore crea e gestisce i ruoli degli utenti. I ruoli sono un insieme configurabile di permessi che definiscono le azioni che l\'utente può compiere all\'interno dell\'applicazione.', + 'role.help': + "Dalla sezione RUOLI l'amministratore crea e gestisce i ruoli degli utenti. I ruoli sono un insieme configurabile di permessi che definiscono le azioni che l'utente può compiere all'interno dell'applicazione.", 'role.listEmpty': 'Non ci sono RUOLI disponibili', - 'role.name.help': 'Puoi inserire massimo 50 caratteri, lettere maiuscole e minuscole, numeri, e caratteri speciali. ', - 'role.code.help': 'Puoi inserire massimo 20 caratteri, lettere maiuscole e minuscole, numeri, ed il carattere speciale underscore ', + 'role.name.help': + 'Puoi inserire massimo 50 caratteri, lettere maiuscole e minuscole, numeri, e caratteri speciali. ', + 'role.code.help': + 'Puoi inserire massimo 20 caratteri, lettere maiuscole e minuscole, numeri, ed il carattere speciale underscore ', 'role.detail.referencedUsers': 'Utenti referenziati', 'role.detail.noPermissions': 'Non ci sono permessi', 'permission.listEmpty': 'Non ci sono PERMISSION disponibili', @@ -723,17 +832,25 @@ export default { 'reference.jacmsResourceManager': 'Risorse con questa categoria', 'reference.DataObjectManager': 'Data Objects con questa categoria', 'reference.jpcollaborationIdeaManager': 'Ideas con questa categoria', - 'reference.noReferencejacmsContentManager': 'Non ci sono contenuti referenziati', - 'reference.noReferencejacmsResourceManager': 'Non ci sono risorse referenziate', - 'reference.noReferenceDataObjectManager': 'Non ci sono data object referenziati', - 'reference.noReferencejpcollaborationIdeaManager': 'Non ci sono idea referenziate', + 'reference.noReferencejacmsContentManager': + 'Non ci sono contenuti referenziati', + 'reference.noReferencejacmsResourceManager': + 'Non ci sono risorse referenziate', + 'reference.noReferenceDataObjectManager': + 'Non ci sono data object referenziati', + 'reference.noReferencejpcollaborationIdeaManager': + 'Non ci sono idea referenziate', 'references.referencedPages': 'Pagine referenziate', 'reloadConfiguration.title': 'Ricarica la Configurazione', - 'reloadConfiguration.help': 'Dalla sezione RICARICA CONFIGURAZIONE è possibile ricaricare la configurazione del sistema. Questa operazione si rende necessaria dopo la modifica di alcuni parametri.', + 'reloadConfiguration.help': + 'Dalla sezione RICARICA CONFIGURAZIONE è possibile ricaricare la configurazione del sistema. Questa operazione si rende necessaria dopo la modifica di alcuni parametri.', 'reloadConfiguration.reload.title': 'Ricarica la Configurazione', - 'reloadConfiguration.reload.confirm': 'Sei sicuro di voler ricaricare la configurazione?', - 'reloadConfiguration.confirm.success': 'La configurazione di sistema è stata ricaricata.', - 'reloadConfiguration.confirm.error': 'Non è stato possibile ricaricare la configurazione di sistema', + 'reloadConfiguration.reload.confirm': + 'Sei sicuro di voler ricaricare la configurazione?', + 'reloadConfiguration.confirm.success': + 'La configurazione di sistema è stata ricaricata.', + 'reloadConfiguration.confirm.error': + 'Non è stato possibile ricaricare la configurazione di sistema', 'activityStream.newPage': 'ha creato una nuova Pagina', 'activityStream.editPage': 'ha modificato una Pagina', 'activityStream.deletePage': 'ha eliminato una Pagina', @@ -742,43 +859,61 @@ export default { 'activityStream.modifyPage': 'ha modificato una Pagina', 'activityStream.like': 'Like', 'activityStream.writeComment': 'Scrivi un commento', - 'reference.text': 'Le referenze per i seguenti Tipi di Entita\' hanno bisogno di essere ricaricate. Totale da ricaricare: {count}. ', + 'reference.text': + "Le referenze per i seguenti Tipi di Entita' hanno bisogno di essere ricaricate. Totale da ricaricare: {count}. ", 'reference.reload': 'Clicca {link} per ricaricare tutti i data types.', - 'componentRepository.disabled.title': 'Component Repository è disabilitata.', - 'componentRepository.disabled.help': 'È possibile attivarla impostando COMPONENT_REPOSITORY_UI_ENABLED=true nel file .env', + 'componentRepository.disabled.title': + 'Component Repository è disabilitata.', + 'componentRepository.disabled.help': + 'È possibile attivarla impostando COMPONENT_REPOSITORY_UI_ENABLED=true nel file .env', 'componentRepository.menuButton.title': 'Hub', 'componentRepository.component.list.title': 'Entando Hub', - 'componentRepository.component.help': 'Entando Hub è un marketplace da cui l\'utente può installare Widget, Componenti, UX Fragment, Template di Pagina, Modelli di Contenuto e Tipi di Contenuto', - 'componentRepository.sidebar.componentRepositoryFilterTitle': 'Component Repository', + 'componentRepository.component.help': + "Entando Hub è un marketplace da cui l'utente può installare Widget, Componenti, UX Fragment, Template di Pagina, Modelli di Contenuto e Tipi di Contenuto", + 'componentRepository.sidebar.componentRepositoryFilterTitle': + 'Component Repository', 'componentRepository.sidebar.categoryFilterTitle': 'Categorie', 'componentRepository.components.latestVersion': 'Ultima Versione', 'componentRepository.components.notFound': 'Nessun componente disponibile', - 'componentRepository.des.notFound': 'Nessun component repository è stato ancora registrato. Per aggiungere un nuovo component repository fai clic sull\'icona a forma di ingranaggio nell\'angolo in alto a destra di questa pagina', + 'componentRepository.des.notFound': + "Nessun component repository è stato ancora registrato. Per aggiungere un nuovo component repository fai clic sull'icona a forma di ingranaggio nell'angolo in alto a destra di questa pagina", 'componentRepository.components.install': 'Installa', 'componentRepository.components.update': 'Aggiornare', - 'componentRepository.components.installRollback': 'Installazione non riuscita. L\'installazione è stata ripristinata', + 'componentRepository.components.installRollback': + "Installazione non riuscita. L'installazione è stata ripristinata", 'componentRepository.components.installing': 'Installazione {version}', 'componentRepository.components.uninstalling': 'Disinstallazione {version}', - 'componentRepository.components.failedInstall': 'Installazione non riuscita', + 'componentRepository.components.failedInstall': + 'Installazione non riuscita', 'componentRepository.components.installed': 'Installato', - 'componentRepository.components.failedUninstall': 'Disinstallazione non riuscita', + 'componentRepository.components.failedUninstall': + 'Disinstallazione non riuscita', 'componentRepository.components.recheck': 'Ricontrolla', 'componentRepository.components.retry': 'Riprova', 'componentRepository.components.inprogress': 'In Corso', - 'componentRepository.components.notifyInProgress': 'Installazione inaspettatamente ancora in corso. Puoi controllare di nuovo aggiornando la pagina.', - 'componentRepository.components.notifyFailedInstall': 'Si è verificato un errore durante l\'installazione.', - 'componentRepository.components.notifyFailedUninstall': 'Si è verificato un errore durante la disinstallazione.', + 'componentRepository.components.notifyInProgress': + 'Installazione inaspettatamente ancora in corso. Puoi controllare di nuovo aggiornando la pagina.', + 'componentRepository.components.notifyFailedInstall': + "Si è verificato un errore durante l'installazione.", + 'componentRepository.components.notifyFailedUninstall': + 'Si è verificato un errore durante la disinstallazione.', 'componentRepository.components.uninstall': 'Disinstalla', - 'componentRepository.components.confirmUninstall': 'Vuoi veramente disinstallare il componente {name}?', - 'componentRepository.components.cannotUninstall': 'Impossibile disinstallare', + 'componentRepository.components.confirmUninstall': + 'Vuoi veramente disinstallare il componente {name}?', + 'componentRepository.components.cannotUninstall': + 'Impossibile disinstallare', 'componentRepository.components.usage': 'Utilizzo dei componenti: {usage}', 'componentRepository.components.showInstallPlan': 'Piano di installazione', - 'componentRepository.components.showCustomInstallPlan': 'Installazione personalizzata', - 'componentRepository.components.installPlanFailed': 'Impossibile recuperare il piano di installazione', - 'componentRepository.components.downgradeMessage': 'Tieni presente che il downgrade di un pacchetto a una versione precedente può comportare la perdita di funzionalità o dati. Potresti voler rivedere le note di rilascio del pacchetto prima di eseguire un downgrade.', + 'componentRepository.components.showCustomInstallPlan': + 'Installazione personalizzata', + 'componentRepository.components.installPlanFailed': + 'Impossibile recuperare il piano di installazione', + 'componentRepository.components.downgradeMessage': + 'Tieni presente che il downgrade di un pacchetto a una versione precedente può comportare la perdita di funzionalità o dati. Potresti voler rivedere le note di rilascio del pacchetto prima di eseguire un downgrade.', 'componentRepository.components.downgrade': 'Declassamento', 'componentRepository.components.conflict': 'Conflitto', - 'componentRepository.components.conflictMessage': "Non è stato possibile determinare se questa operazione potrebbe implicare un downgrade. Tieni presente che l'installazione di una versione precedente può comportare la perdita di funzionalità o dati. Potresti voler rivedere le note di rilascio del pacchetto prima di procedere.", + 'componentRepository.components.conflictMessage': + "Non è stato possibile determinare se questa operazione potrebbe implicare un downgrade. Tieni presente che l'installazione di una versione precedente può comportare la perdita di funzionalità o dati. Potresti voler rivedere le note di rilascio del pacchetto prima di procedere.", 'componentRepository.components.replace': 'Sostituire', 'componentRepository.components.proceed': 'Vuoi procedere?', 'componentRepository.sidebar.ratingFilter.title': 'Media voto', @@ -799,7 +934,8 @@ export default { 'componentRepository.extraFilters.new': 'Nuovi', 'componentRepository.extraFilters.installed': 'Installati', 'componentRepository.settings.title': 'Configurazione Component Repository', - 'componentRepository.settings.help': 'In questa sezione è possibile aggiungere o gestire le configurazioni di diversi marketplace all\'interno del Component Repository di Entando.', + 'componentRepository.settings.help': + "In questa sezione è possibile aggiungere o gestire le configurazioni di diversi marketplace all'interno del Component Repository di Entando.", 'componentRepository.settings.add': 'Aggiungi Component Repository', 'componentRepository.settings.active': 'Attivo', 'componentRepository.settings.address': 'Indirizzo', @@ -841,7 +977,8 @@ export default { 'singlePageSettings.generalSettings': 'Generale', 'singlePageSettings.pageTitle': 'Titolo della Pagina', 'singlePageSettings.updateSuccess': 'Pagina aggiornata con successo', - 'plugins.noPlugins': 'Nessun plugin installato. Guarda i plugin disponibili sul Component Repository', + 'plugins.noPlugins': + 'Nessun plugin installato. Guarda i plugin disponibili sul Component Repository', 'plugins.installCallToAction': 'Vai al Component Repository', 'widgets.configUi': 'Config UI', 'widgets.addWidget': 'Aggiungi Widget', @@ -861,9 +998,12 @@ export default { 'app.seo.addMetatagType': 'Tipo', 'app.seo.addMetatagValue': 'Valore', 'app.pages.titleHelp': 'Titolo della pagina per scopi SEO', - 'app.seo.descriptionHelp': 'La meta descrizione è un frammento di testo che riassume il contenuto della pagina', - 'app.seo.keywordsHelp': 'Le meta parole chiave sono un frammento di testo che indica le parole chiave principali della pagina, separate da virgola.', - 'app.seo.addMetatagHelp': 'In questa sezione è possibile aggiungere un nuovo metatag (personalizzato o suggerito da un catalogo interno)', + 'app.seo.descriptionHelp': + 'La meta descrizione è un frammento di testo che riassume il contenuto della pagina', + 'app.seo.keywordsHelp': + 'Le meta parole chiave sono un frammento di testo che indica le parole chiave principali della pagina, separate da virgola.', + 'app.seo.addMetatagHelp': + 'In questa sezione è possibile aggiungere un nuovo metatag (personalizzato o suggerito da un catalogo interno)', 'app.seo.inheritLangLabel': 'Utilizza la lingua predefinita', 'pagination.firstPage': 'Prima Pagina', 'pagination.previousPage': 'Pagina Precedente', @@ -884,27 +1024,35 @@ export default { 'widget.navigationBar.config.fromRoot': 'Distante dalla Radice', 'widget.navigationBar.config.type': 'Tipo', 'widget.navigationBar.config.subtreeDepth': 'Profondità del sottoalbero:', - 'widget.navigationBar.config.addNewExpression': 'Aggiungi una nuova espressione', + 'widget.navigationBar.config.addNewExpression': + 'Aggiungi una nuova espressione', 'widget.navigationBar.config.none': 'Nessuno (Non specificato)', 'widget.navigationBar.config.allChildren': 'Tutti i figli della pagina', - 'widget.navigationBar.config.fromTheRootToSelected': 'Dalla Radice alla pagina scelta', + 'widget.navigationBar.config.fromTheRootToSelected': + 'Dalla Radice alla pagina scelta', 'widget.navigationBar.config.subtree': 'Sottoalbero', - 'widget.navigationBar.config.noExpressions': 'Configura qualche espressione..', + 'widget.navigationBar.config.noExpressions': + 'Configura qualche espressione..', 'widget.update.success': 'Il widget è stato aggiornato!', 'widget.navigationBar.config.subtreeDepthAbr': 'Profondità del sottoalbero', 'info.license': 'Licenza', - 'info.license.description': 'La piattaforma Entando è open source al 100% e nel suo insieme è concessa in licenza con LGPL v3.0. \n\nUna licenza commerciale open source gratuita è disponibile per la piattaforma Entando e l\'Hub Entando per i clienti con abbonamenti Gold e Platinum.\nCon questa licenza, puoi estendere o modificare liberamente Entando senza richiedere il contributo di IP riservato alla community open source.\n\nL\'Abbonamento dà diritto a ricevere servizi di supporto, intesi come manutenzione e garanzia del software (correzione di bug), per tutti i prodotti e componenti sottoscritti per tutta la durata del contratto.', + 'info.license.description': + "La piattaforma Entando è open source al 100% e nel suo insieme è concessa in licenza con LGPL v3.0. \n\nUna licenza commerciale open source gratuita è disponibile per la piattaforma Entando e l'Hub Entando per i clienti con abbonamenti Gold e Platinum.\nCon questa licenza, puoi estendere o modificare liberamente Entando senza richiedere il contributo di IP riservato alla community open source.\n\nL'Abbonamento dà diritto a ricevere servizi di supporto, intesi come manutenzione e garanzia del software (correzione di bug), per tutti i prodotti e componenti sottoscritti per tutta la durata del contratto.", 'info.license.type': 'LGPL v3.0 licenza', 'info.about': 'Informazioni', 'info.about.entandoPlatform': 'Entando Platform', - 'info.about.entando': 'Entando è la principale Application Composition Platform open source per Kubernetes. Consente a team che lavorano in parallelo di accelerare lo sviluppo e l\'innovazione delle funzionalità aziendali su uno stack moderno, cloud-native e Kubernetes-native', - 'info.about.docs': 'La documentazione ti fa conoscere la piattaforma Entando e ti guida nell\'esplorazione delle sue funzionalità. Per iniziare ad utilizzare la piattaforma Entando, visita', + 'info.about.entando': + "Entando è la principale Application Composition Platform open source per Kubernetes. Consente a team che lavorano in parallelo di accelerare lo sviluppo e l'innovazione delle funzionalità aziendali su uno stack moderno, cloud-native e Kubernetes-native", + 'info.about.docs': + "La documentazione ti fa conoscere la piattaforma Entando e ti guida nell'esplorazione delle sue funzionalità. Per iniziare ad utilizzare la piattaforma Entando, visita", 'info.about.version': 'Versione {version}', - 'reference.text.success': 'I riferimenti devono essere ricaricati ogni volta che viene modificato un profilo.', + 'reference.text.success': + 'I riferimenti devono essere ricaricati ogni volta che viene modificato un profilo.', 'reference.label.success': 'Va tutto bene.', 'reference.status.title': 'Stato di riferimento', 'user.table.profileType': 'Tipo di profilo', - 'app.deleteRoleImpossible': 'Il ruolo non può essere eliminato finché non viene rimosso da tutti i seguenti utenti', + 'app.deleteRoleImpossible': + 'Il ruolo non può essere eliminato finché non viene rimosso da tutti i seguenti utenti', 'app.saveAs': 'Salva come', 'menu.widgetClone': 'Clona widget', 'widget.page.clone.pageTitle': 'Clona widget', @@ -912,72 +1060,104 @@ export default { 'user.myProfile.appSettingsSection': 'Preferenze', 'user.myProfile.disableContentMenu': 'Disabilita il menu dei contenuti', 'user.myProfile.wizardToggle': 'Welcome Wizard', - 'user.myProfile.wizardToggleHelp': 'Abilita o disabilita la procedura guidata di benvenuto che guida l\'utente attraverso il processo "Crea prima applicazione"', + 'user.myProfile.wizardToggleHelp': + 'Abilita o disabilita la procedura guidata di benvenuto che guida l\'utente attraverso il processo "Crea prima applicazione"', 'user.myProfile.translationWarning': 'Avviso di traduzione mancante', - 'user.myProfile.translationWarningHelp': 'Abilita o disabilita il messaggio di avviso per ricordarti di riempire i campi di traduzione di un contenuto.', + 'user.myProfile.translationWarningHelp': + 'Abilita o disabilita il messaggio di avviso per ricordarti di riempire i campi di traduzione di un contenuto.', 'user.myProfile.loadOnPageSelect': 'Carica su selezione pagina', - 'user.myProfile.loadOnPageSelectHelp': 'Carica una pagina della struttura ad albero della pagina nel designer della pagina dopo averla selezionata.', - 'user.myProfile.defaultPageOwnerGroup': 'Gruppo proprietario pagina predefinito', - 'user.myProfile.defaultPageOwnerGroupHelp': 'Imposta il gruppo proprietario predefinito durante la creazione di una pagina.', - 'user.myProfile.defaultPageJoinGroups': 'Pagina predefinita Unisciti ai gruppi', - 'user.myProfile.defaultPageJoinGroupsHelp': 'Imposta i gruppi di partecipazione predefiniti durante la creazione di una pagina.', - 'user.myProfile.defaultContentOwnerGroup': 'Gruppo di proprietari dei contenuti predefinito', - 'user.myProfile.defaultContentOwnerGroupHelp': 'Imposta il gruppo proprietario predefinito durante la creazione di un contenuto.', - 'user.myProfile.defaultContentJoinGroups': 'Contenuto predefinito Partecipa a gruppi', - 'user.myProfile.defaultContentJoinGroupsHelp': 'Imposta i gruppi di partecipazione predefiniti durante la creazione di un contenuto.', - 'user.myProfile.defaultWidgetOwnerGroup': 'Gruppo proprietario widget predefinito', - 'user.myProfile.defaultWidgetOwnerGroupHelp': 'Imposta il gruppo proprietario predefinito quando si crea un widget o un MFE.', + 'user.myProfile.loadOnPageSelectHelp': + 'Carica una pagina della struttura ad albero della pagina nel designer della pagina dopo averla selezionata.', + 'user.myProfile.defaultPageOwnerGroup': + 'Gruppo proprietario pagina predefinito', + 'user.myProfile.defaultPageOwnerGroupHelp': + 'Imposta il gruppo proprietario predefinito durante la creazione di una pagina.', + 'user.myProfile.defaultPageJoinGroups': + 'Pagina predefinita Unisciti ai gruppi', + 'user.myProfile.defaultPageJoinGroupsHelp': + 'Imposta i gruppi di partecipazione predefiniti durante la creazione di una pagina.', + 'user.myProfile.defaultContentOwnerGroup': + 'Gruppo di proprietari dei contenuti predefinito', + 'user.myProfile.defaultContentOwnerGroupHelp': + 'Imposta il gruppo proprietario predefinito durante la creazione di un contenuto.', + 'user.myProfile.defaultContentJoinGroups': + 'Contenuto predefinito Partecipa a gruppi', + 'user.myProfile.defaultContentJoinGroupsHelp': + 'Imposta i gruppi di partecipazione predefiniti durante la creazione di un contenuto.', + 'user.myProfile.defaultWidgetOwnerGroup': + 'Gruppo proprietario widget predefinito', + 'user.myProfile.defaultWidgetOwnerGroupHelp': + 'Imposta il gruppo proprietario predefinito quando si crea un widget o un MFE.', 'tour.start.welcome': 'Benvenuto in Entando', 'user.wizard.success': 'Wizard è stato aggiornato.', 'app.next': 'Avanti', 'tour.start.title': 'Crea la tua prima applicazione', - 'tour.start.description': 'Usa questa procedura guidata per creare la tua prima pagina. Ti guiderà attraverso tutti i passaggi necessari per creare e progettare una pagina', + 'tour.start.description': + 'Usa questa procedura guidata per creare la tua prima pagina. Ti guiderà attraverso tutti i passaggi necessari per creare e progettare una pagina', 'tour.start.dontShow': 'Non mostrare la prossima volta', 'tour.step.2.main': 'Crea la tua prima applicazione', 'tour.step.2.title': 'Entando AppBuilder', - 'tour.step.2.description': 'L\'AppBuilder è dove creerai tutte le tue app utilizzando contenuti web, micro frontend e microservizi.', + 'tour.step.2.description': + "L'AppBuilder è dove creerai tutte le tue app utilizzando contenuti web, micro frontend e microservizi.", 'tour.step.cancel.title': 'Sei sicuro di voler uscire dal tutorial?', 'tour.step.3.title': 'Crea la Home Page', - 'tour.step.3.description': 'Il primo passo da fare è creare la nostra home page. Fai clic su Pagine nella barra laterale sinistra.', + 'tour.step.3.description': + 'Il primo passo da fare è creare la nostra home page. Fai clic su Pagine nella barra laterale sinistra.', 'tour.step.4.title': 'Gestione della pagina', 'tour.step.4.description': 'Quindi, fai clic su Gestione.', 'tour.step.5.title': 'Crea una pagina', - 'tour.step.5.description': 'Qui vedrai un elenco di pagine che rappresentano l\'albero delle pagine del tuo sito. Fare clic su Aggiungi per creare una nuova pagina.', + 'tour.step.5.description': + "Qui vedrai un elenco di pagine che rappresentano l'albero delle pagine del tuo sito. Fare clic su Aggiungi per creare una nuova pagina.", 'tour.step.6.title': 'Scegli il titolo della pagina', - 'tour.step.6.description': 'Questo serve come titolo della tua pagina per scopi SEO.', + 'tour.step.6.description': + 'Questo serve come titolo della tua pagina per scopi SEO.', 'tour.step.7.title': 'Scegliere un codice per la pagina', - 'tour.step.7.description': 'Il codice della pagina viene utilizzato per identificare in modo univoco una pagina e per la ricerca. Nel nostro esempio, utilizziamo tutti "hello_world app" per il codice della pagina.', - 'tour.step.8.title': 'Scegli la posizione della pagina all\'interno del tuo sito', + 'tour.step.7.description': + 'Il codice della pagina viene utilizzato per identificare in modo univoco una pagina e per la ricerca. Nel nostro esempio, utilizziamo tutti "hello_world app" per il codice della pagina.', + 'tour.step.8.title': + "Scegli la posizione della pagina all'interno del tuo sito", 'tour.step.8.description': 'Scegli la posizione della tua pagina', 'tour.step.9.title': 'Scegli a che gruppo appartiene', 'tour.step.9.description': 'Scegli a che gruppo appartiene', 'tour.step.10.title': 'Scegli il modello di pagina', 'tour.step.10.description': 'Scegli il modello di pagina', 'tour.step.11.title': 'Salva e progetta', - 'tour.step.11.description': 'Una volta salvate le nostre impostazioni, possiamo iniziare a progettare la nostra pagina.', + 'tour.step.11.description': + 'Una volta salvate le nostre impostazioni, possiamo iniziare a progettare la nostra pagina.', 'tour.step.12.title': 'Aggiungi widget', - 'tour.step.12.description': 'Nella barra laterale destra, espandi il menu Pagina. Quindi trascina e rilascia il widget Logo nella sezione \'Logo\' grigia tratteggiata sulla pagina.', + 'tour.step.12.description': + "Nella barra laterale destra, espandi il menu Pagina. Quindi trascina e rilascia il widget Logo nella sezione 'Logo' grigia tratteggiata sulla pagina.", 'tour.step.13.title': 'Aggiungi widget', - 'tour.step.13.description': 'Fare clic su Avanti per aggiungere il widget del menu di navigazione preconfigurato al design della pagina per il menu orizzontale di primo livello', + 'tour.step.13.description': + 'Fare clic su Avanti per aggiungere il widget del menu di navigazione preconfigurato al design della pagina per il menu orizzontale di primo livello', 'tour.step.14.title': 'Aggiungi widget', - 'tour.step.14.description': 'Nella barra laterale destra, espandi il menu CMS. Quindi trascina e rilascia il widget \'Barra ricerca\' nella sezione \'Search\' grigia tratteggiata nella pagina.', + 'tour.step.14.description': + "Nella barra laterale destra, espandi il menu CMS. Quindi trascina e rilascia il widget 'Barra ricerca' nella sezione 'Search' grigia tratteggiata nella pagina.", 'tour.step.15.title': 'Aggiungi widget', - 'tour.step.15.description': 'Nella barra laterale destra, espandi il menu di sistema. Quindi trascina e rilascia il widget \'Login\' nella sezione \'Login\' tratteggiata nella pagina.', + 'tour.step.15.description': + "Nella barra laterale destra, espandi il menu di sistema. Quindi trascina e rilascia il widget 'Login' nella sezione 'Login' tratteggiata nella pagina.", 'tour.step.16.title': 'Aggiungi widget', - 'tour.step.16.description': 'Fare clic su Avanti per aggiungere il widget Contenuto preconfigurato alla pagina', + 'tour.step.16.description': + 'Fare clic su Avanti per aggiungere il widget Contenuto preconfigurato alla pagina', 'tour.step.17.title': 'Aggiungi widget', - 'tour.step.17.description': 'Fare clic su Avanti per aggiungere il widget Elenco contenuti preconfigurato alla pagina', + 'tour.step.17.description': + 'Fare clic su Avanti per aggiungere il widget Elenco contenuti preconfigurato alla pagina', 'tour.step.18.title': 'Aggiungi widget', - 'tour.step.18.description': 'Fare clic su Avanti per aggiungere il widget del menu di navigazione preconfigurato e aggiungere il collegamento alla mappa del sito nel piè di pagina', + 'tour.step.18.description': + 'Fare clic su Avanti per aggiungere il widget del menu di navigazione preconfigurato e aggiungere il collegamento alla mappa del sito nel piè di pagina', 'tour.step.19.title': 'Anteprima', - 'tour.step.19.description': 'Fai clic su Anteprima per vedere come apparirà la tua pagina prima di pubblicarla.', + 'tour.step.19.description': + 'Fai clic su Anteprima per vedere come apparirà la tua pagina prima di pubblicarla.', 'tour.step.20.title': 'Pubblicare', - 'tour.step.20.description': 'Fai clic su Pubblica per vedere la tua pagina dal vivo.', + 'tour.step.20.description': + 'Fai clic su Pubblica per vedere la tua pagina dal vivo.', 'app.startTutorial': 'Inizia il tutorial', 'emailConfig.smtpServer': 'SMTP Server', 'emailConfig.senderMgmt': 'Configura i Mittenti', - 'emailConfig.help': 'Il plugin Configurazione email fornisce funzionalità di base per inviare email. Questo plugin è un prerequisito per tutti i plugin che richiedono la consegna di posta elettronica. Gli amministratori devono configurare la configurazione di rete e creare almeno un profilo mittente.', - 'emailConfig.smtpServer.panelMsg': 'Host è obbligatorio. Port e Timeout se vuoti, verranno impostati per impostazione predefinita su 25 e 10000. Lasciare il campo Nome utente e password vuoti se il server SMTP non richiede l\'autenticazione.', + 'emailConfig.help': + 'Il plugin Configurazione email fornisce funzionalità di base per inviare email. Questo plugin è un prerequisito per tutti i plugin che richiedono la consegna di posta elettronica. Gli amministratori devono configurare la configurazione di rete e creare almeno un profilo mittente.', + 'emailConfig.smtpServer.panelMsg': + "Host è obbligatorio. Port e Timeout se vuoti, verranno impostati per impostazione predefinita su 25 e 10000. Lasciare il campo Nome utente e password vuoti se il server SMTP non richiede l'autenticazione.", 'emailConfig.smtpServer.generalSettings': 'Impostazioni Generali', 'emailConfig.smtpServer.active': 'Attivo', 'emailConfig.smtpServer.debugMode': 'Debug Mode', @@ -985,23 +1165,28 @@ export default { 'emailConfig.smtpServer.host': 'Host', 'emailConfig.smtpServer.port': 'Port', 'emailConfig.smtpServer.security': 'Security', - 'emailConfig.smtpServer.checkServerIdentity': 'Controlla l\'identità del server', + 'emailConfig.smtpServer.checkServerIdentity': + "Controlla l'identità del server", 'emailConfig.smtpServer.timeout': 'Timeout (in millisecondi)', 'emailConfig.smtpServer.authentication': 'Autenticazione', 'emailConfig.smtpServer.username': 'Username', 'emailConfig.smtpServer.password': 'Password', 'emailConfig.smtpServer.testConfig': 'Configurazione di prova', - 'emailConfig.smtpServer.sendTestEmail': 'Invia un\'email di prova', + 'emailConfig.smtpServer.sendTestEmail': "Invia un'email di prova", 'emailConfig.senderMgmt.email': 'Email', 'emailConfig.senderMgmt.new': 'Nuovo mittente', 'emailConfig.senderMgmt.edit': 'Modifica mittente', 'emailConfig.senderMgmt.editWithCode': 'Modifica mittente: {code}', 'emailConfig.saveSuccessful': 'Configurazione e-mail salvata con successo.', - 'emailConfig.valid': 'La configurazione dell\'email è valida.', - 'app.pages.friendlyCodeHelp': 'URL slug per la pagina. Puoi inserire massimo 100 caratteri, lettere minuscole, numeri, ed il carattere speciali \'_\' e \'-\'.', - 'validateForm.friendlyCode': 'Il Friendly Code può solo contenere lettere minuscole, numeri o caratteri i speciali \'_\' e \'-\'.', - 'validateForm.friendlyCodeWithDash': 'Il Friendly Code può solo contenere lettere minuscole, numeri o caratteri i speciali \'_\' e \'-\'.', - 'validateForm.friendlyCodeUnique': 'Il Friendly Code deve essere univoco per tutte le lingue.', + 'emailConfig.valid': "La configurazione dell'email è valida.", + 'app.pages.friendlyCodeHelp': + "URL slug per la pagina. Puoi inserire massimo 100 caratteri, lettere minuscole, numeri, ed il carattere speciali '_' e '-'.", + 'validateForm.friendlyCode': + "Il Friendly Code può solo contenere lettere minuscole, numeri o caratteri i speciali '_' e '-'.", + 'validateForm.friendlyCodeWithDash': + "Il Friendly Code può solo contenere lettere minuscole, numeri o caratteri i speciali '_' e '-'.", + 'validateForm.friendlyCodeUnique': + 'Il Friendly Code deve essere univoco per tutte le lingue.', 'pageTree.searchForm.searchPageBy': 'Pagina di ricerca per', 'pageTree.searchForm.name': 'Nome pagina', 'pageTree.searchForm.search.name': 'Ricerca per nome', @@ -1063,7 +1248,7 @@ export default { 'cms.label.errors': 'Errori', 'cms.label.moveUp': 'Muovi Su', 'cms.label.moveDown': 'Muovi Giù', - 'cms.label.chooseoption': 'Seleziona un\'opzione', + 'cms.label.chooseoption': "Seleziona un'opzione", 'cms.label.chooseOptions': 'Scegli le opzioni', 'cms.label.noOptions': 'Senza ulteriori opzioni', 'cms.label.noMatchOptions': 'Nessun risultato trovato', @@ -1086,15 +1271,19 @@ export default { 'cms.label.date.placeholder': 'gg/mm/anno', 'cms.label.presenter.placeholder': 'Premi INVIO per salvare le modifiche', 'cms.label.modal.confirmdelete': 'Sei sicuro di voler rimuovere {code}?', - 'cms.label.modal.confirmDeleteVersion': 'Sei sicuro di volere eliminare definitivamente la versione {version}?', - 'cms.label.modal.confirmRestore': 'Vuoi davvero ripristinare questa versione {version}? Confermando, l\'ultima versione verrà sostituita con questa.', - 'cms.label.modal.confirmCancel': 'Vuoi salvare le modifiche apportate? Le modifiche andranno perse se non le salvi', + 'cms.label.modal.confirmDeleteVersion': + 'Sei sicuro di volere eliminare definitivamente la versione {version}?', + 'cms.label.modal.confirmRestore': + "Vuoi davvero ripristinare questa versione {version}? Confermando, l'ultima versione verrà sostituita con questa.", + 'cms.label.modal.confirmCancel': + 'Vuoi salvare le modifiche apportate? Le modifiche andranno perse se non le salvi', 'cms.label.dontSave': 'Non salvare', 'cms.label.metadata': 'Metadati', 'cms.contents.versioning.author': 'Autore', 'cms.versioning.list.lastModify': 'Ultima modifica', 'cms.label.modal.confirmpublish': 'Vuoi davvero pubblicare {code}?', - 'cms.label.modal.confirmunpublish': 'Vuoi davvero annullare la pubblicazione di {code}?', + 'cms.label.modal.confirmunpublish': + 'Vuoi davvero annullare la pubblicazione di {code}?', 'cms.label.yes': 'sì', 'cms.label.no': 'no', 'cms.label.all': 'tutti', @@ -1115,12 +1304,13 @@ export default { 'cms.menu.scheduler': 'Scheduler', 'cms.assets.title': 'Risorse', 'cms.assets.list.all': 'Tutte', - 'cms.datetimepicker.label.hours': 'Scegli un\'ora', + 'cms.datetimepicker.label.hours': "Scegli un'ora", 'cms.datetimepicker.label.minutes': 'Scegli un minuto', 'cms.datetimepicker.label.seconds': 'Scegli un secondo', 'cms.contenttemplate.title': 'Template di Contenuto', 'cms.contenttemplate.titletip': 'Puoi creare un template di contenuto qui', - 'cms.contenttemplate.titletip.edit': 'È possibile modificare il template di contenuto qui', + 'cms.contenttemplate.titletip.edit': + 'È possibile modificare il template di contenuto qui', 'cms.contenttemplate.searchPlaceholder': 'Cerca template di contenuto', 'cms.contenttemplate.searchFilter.label': 'Cercato da', 'cms.contenttemplate.add.label': 'Aggiungi', @@ -1129,28 +1319,43 @@ export default { 'cms.contenttemplate.searchFilter.valueName': 'Nome', 'cms.contenttemplate.list.contentTypeHeader': 'Tipo di contenuto', 'cms.contenttemplate.list.contentTypeIdHeader': 'Codice', - 'cms.contenttemplate.list.contentTemplateNameHeader': 'Nome template di contenuto', + 'cms.contenttemplate.list.contentTemplateNameHeader': + 'Nome template di contenuto', 'cms.contenttemplate.list.actionsHeader': 'Azioni', 'cms.contenttemplate.list.infoDeleted': '{modelname} rimosso', 'cms.contenttemplate.form.code': 'Codice', 'cms.contenttemplate.form.codePlaceholder': 'Codice', - 'cms.contenttemplate.form.codeHelp': 'È possibile inserire fino a 10 numeri', - 'cms.contenttemplate.form.nameHelp': 'È possibile inserire fino a 50 caratteri inclusi lettere maiuscole e minuscole, numeri e caratteri speciali', - 'cms.contenttemplate.form.contentTypeHelp': 'Scegli uno dei tipi di contenuto esistenti da utilizzare per il tuo template di contenuto', + 'cms.contenttemplate.form.codeHelp': + 'È possibile inserire fino a 10 numeri', + 'cms.contenttemplate.form.nameHelp': + 'È possibile inserire fino a 50 caratteri inclusi lettere maiuscole e minuscole, numeri e caratteri speciali', + 'cms.contenttemplate.form.contentTypeHelp': + 'Scegli uno dei tipi di contenuto esistenti da utilizzare per il tuo template di contenuto', 'cms.contenttemplate.form.htmlmodel': 'Modello HTML', - 'cms.contenttemplate.form.htmlmodelHelp': 'Questa sarà la tua struttura di contenuto HTML usando gli elementi di contenuto forniti da un determinato tipo di contenuto', - 'cms.contenttemplate.form.htmlmodel.statusassist': 'l\'assistente ai contenuti è ATTIVO', - 'cms.contenttemplate.form.htmlmodel.statusattrhelp': 'Aiuto Informazioni sul tipo di attributi è DISATTIVATO', - 'cms.contenttemplate.form.htmlmodel.statusadminconf': 'Se si desidera modificare lo stato, è necessario impostarli nell\'area di configurazione dell\'amministratore', - 'cms.contenttemplate.form.saved': 'Template di contenuto "{modelname}" Salvato', - 'cms.contenttemplate.form.editassistant': 'Assistente per la Modifica in Linea', + 'cms.contenttemplate.form.htmlmodelHelp': + 'Questa sarà la tua struttura di contenuto HTML usando gli elementi di contenuto forniti da un determinato tipo di contenuto', + 'cms.contenttemplate.form.htmlmodel.statusassist': + "l'assistente ai contenuti è ATTIVO", + 'cms.contenttemplate.form.htmlmodel.statusattrhelp': + 'Aiuto Informazioni sul tipo di attributi è DISATTIVATO', + 'cms.contenttemplate.form.htmlmodel.statusadminconf': + "Se si desidera modificare lo stato, è necessario impostarli nell'area di configurazione dell'amministratore", + 'cms.contenttemplate.form.saved': + 'Template di contenuto "{modelname}" Salvato', + 'cms.contenttemplate.form.editassistant': + 'Assistente per la Modifica in Linea', 'cms.contenttemplate.form.stylesheet': 'Foglio di Stile', - 'cms.contenttemplate.form.stylesheetHelp': 'Fornisci un file di foglio di stile da utilizzare con il tuo modello HTML', - 'cms.contenttemplate.form.editassist.dialog': 'Di seguito un esempio su come utilizzare l\'INLINE EDITING in Entando labels

  1. aprire un TAG tipo div p span...
  2. aggiungere al TAG la classe \'edit content\'. Nota bene che la classe \'editContentText\' viene utilizzato in caso di text area
  3. poi aggiungere data-content-id="$content.getId()"
  4. aggiungere infine l\' ID dell\'attributo (TITLE) che volete stampare scrivendo data-attr-id="TITLE" e chiudere il tag con >. Fare attenzione in quanto lattributo ID é case sensitive e deve essere lo stesso di quello usato nel prossimo step
  5. adesso inserite la label dell\'attributo che volete stampare aggiungendo $content.TITLE.text
  6. chiudete ilTAG (div p span ...) aperto all\'inizio.
Il risultato dovrebbe essere così:

OPEN TAG class="editContent" data-content-id="$content.getId()" data-attr-id="TITLE">
$content.TITLE.text
CLOSE TAG', - 'cms.contenttemplate.form.presscontext': '(premi ctrl + spazio per aprire il menu di assistenza ai contenuti)', - 'cms.contenttemplate.delete.messageprompt': 'Sei sicuro di voler rimuovere {id} ({descr})?', + 'cms.contenttemplate.form.stylesheetHelp': + 'Fornisci un file di foglio di stile da utilizzare con il tuo modello HTML', + 'cms.contenttemplate.form.editassist.dialog': + 'Di seguito un esempio su come utilizzare l\'INLINE EDITING in Entando labels

  1. aprire un TAG tipo div p span...
  2. aggiungere al TAG la classe \'edit content\'. Nota bene che la classe \'editContentText\' viene utilizzato in caso di text area
  3. poi aggiungere data-content-id="$content.getId()"
  4. aggiungere infine l\' ID dell\'attributo (TITLE) che volete stampare scrivendo data-attr-id="TITLE" e chiudere il tag con >. Fare attenzione in quanto lattributo ID é case sensitive e deve essere lo stesso di quello usato nel prossimo step
  5. adesso inserite la label dell\'attributo che volete stampare aggiungendo $content.TITLE.text
  6. chiudete ilTAG (div p span ...) aperto all\'inizio.
Il risultato dovrebbe essere così:

OPEN TAG class="editContent" data-content-id="$content.getId()" data-attr-id="TITLE">
$content.TITLE.text
CLOSE TAG', + 'cms.contenttemplate.form.presscontext': + '(premi ctrl + spazio per aprire il menu di assistenza ai contenuti)', + 'cms.contenttemplate.delete.messageprompt': + 'Sei sicuro di voler rimuovere {id} ({descr})?', 'cms.contenttype.title': 'Tipi di Contenuto', - 'cms.contenttype.titletip': 'La sezione Tipi di contenuto consente all\'amministratore di aggiungere nuovi tipi di contenuto o modificare quelli già esistenti. Puoi creare un tipo di contenuto qui.', + 'cms.contenttype.titletip': + "La sezione Tipi di contenuto consente all'amministratore di aggiungere nuovi tipi di contenuto o modificare quelli già esistenti. Puoi creare un tipo di contenuto qui.", 'cms.contenttype.add.label': 'Aggiungi', 'cms.contenttype.edit.label': 'Modifica', 'cms.contenttype.list.contentTypeNameHeader': 'Nome', @@ -1159,18 +1364,25 @@ export default { 'cms.contenttype.list.actionsHeader': 'Azioni', 'cms.contenttype.list.status': 'Stato', 'cms.contenttype.list.status.0': 'A posto. Se vuoi, ricarica', - 'cms.contenttype.list.status.1': 'Ricaricamento in corso. Aggiorna la pagina.', - 'cms.contenttype.list.status.2': 'È necessario un ricaricamento: lancialo ora.', - 'cms.contenttype.reference.text': 'I seguenti riferimenti devoo essere ricaricati: {types}. Totale da ricaricare: {count}. ', - 'cms.contenttype.reference.reload': 'Clicca {link} per ricaricare tutti i content types.', + 'cms.contenttype.list.status.1': + 'Ricaricamento in corso. Aggiorna la pagina.', + 'cms.contenttype.list.status.2': + 'È necessario un ricaricamento: lancialo ora.', + 'cms.contenttype.reference.text': + 'I seguenti riferimenti devoo essere ricaricati: {types}. Totale da ricaricare: {count}. ', + 'cms.contenttype.reference.reload': + 'Clicca {link} per ricaricare tutti i content types.', 'cms.contenttype.attributes.label': 'Attributi', - 'cms.contentType.helpattributes.label': 'Dalla sezione tipi di contenuto l\'amministratore può creare nuovi tipi di dati o modificare quelli già esistenti.', + 'cms.contentType.helpattributes.label': + "Dalla sezione tipi di contenuto l'amministratore può creare nuovi tipi di dati o modificare quelli già esistenti.", 'cms.contenttype.datatype.label': 'Tipo', 'cms.contenttype.datatype.code.label': 'Codice', 'cms.contenttype.form.type': 'Tipo', 'cms.contenttype.form.code': 'Codice', - 'cms.contenttype.form.codeHelp': 'Puoi inserire caratteri, lettere maiuscole e minuscole, numeri, ed il carattere speciale _', - 'cms.contenttype.attribute.codeHelp': 'Il codice è valido solo se composto da 3 lettere maiuscole', + 'cms.contenttype.form.codeHelp': + 'Puoi inserire caratteri, lettere maiuscole e minuscole, numeri, ed il carattere speciale _', + 'cms.contenttype.attribute.codeHelp': + 'Il codice è valido solo se composto da 3 lettere maiuscole', 'cms.contenttype.attribute.label.listOf': 'Lista di', 'cms.contenttype.form.name': 'Nome', 'cms.contenttype.form.role': 'Ruolo', @@ -1178,62 +1390,88 @@ export default { 'cms.contenttype.form.mandatory': 'Obbligatorio', 'cms.contenttype.form.filter': 'Filtro', 'cms.contenttype.form.actions': 'Azioni', - 'cms.contenttype.form.filterList': 'Può essere usato come filtro nelle liste', - 'cms.contenttype.form.metadata.defaultContentTemplate': 'Template di contenuto predefinito', - 'cms.contenttype.form.metadata.defaultContentTemplateLists': 'Template di contenuto predefinito per elenchi', - 'cms.contenttype.form.metadata.viewPage': 'Pagina per la pubblicazione al volo', + 'cms.contenttype.form.filterList': + 'Può essere usato come filtro nelle liste', + 'cms.contenttype.form.metadata.defaultContentTemplate': + 'Template di contenuto predefinito', + 'cms.contenttype.form.metadata.defaultContentTemplateLists': + 'Template di contenuto predefinito per elenchi', + 'cms.contenttype.form.metadata.viewPage': + 'Pagina per la pubblicazione al volo', 'cms.contenttype.alert.created': 'tipo di contenuto creato con successo', - 'cms.contenttype.attribute.edit.title': 'Modifica attributo per un tipo di contenuto', - 'cms.contenttype.attribute.add.title': 'Aggiungi attributo per un tipo di contenuto', + 'cms.contenttype.attribute.edit.title': + 'Modifica attributo per un tipo di contenuto', + 'cms.contenttype.attribute.add.title': + 'Aggiungi attributo per un tipo di contenuto', 'cms.contenttype.enumeratorStaticItems': 'Elementi', - 'cms.contenttype.enumeratorStaticItems.help': 'Inserisci una configuration tipo "label1,label2,label3"', - 'cms.contenttype.enumeratorStaticItemsMap.help': 'Inserisci una configuration tipo "key1=value1,key2=value2,key3=value3"', + 'cms.contenttype.enumeratorStaticItems.help': + 'Inserisci una configuration tipo "label1,label2,label3"', + 'cms.contenttype.enumeratorStaticItemsMap.help': + 'Inserisci una configuration tipo "key1=value1,key2=value2,key3=value3"', 'cms.contenttype.enumeratorStaticItemsSeparator': 'Separatore', 'cms.contenttype.enumeratorExtractorBean': 'Estrattore del bean name', 'cms.contenttype.ognl.validation': 'Validazione - OGNL', - 'cms.contenttype.ognl.validation.help1': 'In questa sezione puoi inserire le validazioni sull\'Attributo.', - 'cms.contenttype.ognl.validation.help2': 'L\'espressione OGNL deve restituire un valore Boolean (true o false). Nella costruzione delle espressioni, l\'oggetto "root" è l\'attributo stesso (si può accedere ai metodi dell\'attributo senza specificarlo o tramite il prefisso #attribute).', - 'cms.contenttype.ognl.validation.help3': 'Sono disponibili: la mappa delle lingue del sistema (#langs) e l\'Entità a cui è associato (#entity).', - 'cms.contenttype.ognl.validation.help4': 'Inoltre per gli elementi di una Lista o di un Composito è possibile accedere al padre dell\'attributo (#parent) e per gli elementi di una Lista si ha a disposizione l\'indice (#index).', + 'cms.contenttype.ognl.validation.help1': + "In questa sezione puoi inserire le validazioni sull'Attributo.", + 'cms.contenttype.ognl.validation.help2': + "L'espressione OGNL deve restituire un valore Boolean (true o false). Nella costruzione delle espressioni, l'oggetto \"root\" è l'attributo stesso (si può accedere ai metodi dell'attributo senza specificarlo o tramite il prefisso #attribute).", + 'cms.contenttype.ognl.validation.help3': + "Sono disponibili: la mappa delle lingue del sistema (#langs) e l'Entità a cui è associato (#entity).", + 'cms.contenttype.ognl.validation.help4': + "Inoltre per gli elementi di una Lista o di un Composito è possibile accedere al padre dell'attributo (#parent) e per gli elementi di una Lista si ha a disposizione l'indice (#index).", 'cms.contenttype.ognl.expression': 'Espressione OGNL ', - 'cms.contenttype.apply.expression': 'Usa l\'espressione solo se l\'attributo è valorizzato', - 'cms.contenttype.ognl.validation.add.message.help': 'Si possono inserire sia un messagio d\'aiuto che un messagio di errore, oppure una chiave per collegarli alle etichette di sistema', - 'cms.contenttype.ognl.message': 'Messaggio d\'aiuto', - 'cms.contenttype.help.message': 'Messaggio d\'aiuto', - 'cms.contenttype.help.message.key': 'Chiave per il messagio d\'aiuto', - 'cms.contenttype.error.message': 'Messaggio d\'errore', + 'cms.contenttype.apply.expression': + "Usa l'espressione solo se l'attributo è valorizzato", + 'cms.contenttype.ognl.validation.add.message.help': + "Si possono inserire sia un messagio d'aiuto che un messagio di errore, oppure una chiave per collegarli alle etichette di sistema", + 'cms.contenttype.ognl.message': "Messaggio d'aiuto", + 'cms.contenttype.help.message': "Messaggio d'aiuto", + 'cms.contenttype.help.message.key': "Chiave per il messagio d'aiuto", + 'cms.contenttype.error.message': "Messaggio d'errore", 'cms.contenttype.error.message.key': 'Chiave per il messaggio di errore', 'cms.contenttype.labelrole.choose': 'Scegli un ruolo', 'cms.contenttype.labelrole.assigned': 'Assigned role', - 'cms.contenttype.labelrole.noroles': 'Ruoli non disponibili o potrebbero già essere stati assegnati.', - 'cms.contenttype.label.working': 'Stai lavorando sull\'attributo:', + 'cms.contenttype.labelrole.noroles': + 'Ruoli non disponibili o potrebbero già essere stati assegnati.', + 'cms.contenttype.label.working': "Stai lavorando sull'attributo:", 'cms.contenttype.label.element.of': 'elemento di', 'cms.contenttype.label.edit.attribute': 'Modifica : attributo - ', 'cms.contenttype.label.edit.Monolist': 'Modifica : Monolist', 'cms.contenttype.label.edit.List': 'Modifica : Lista', 'cms.contentsettings.title': ' Impostazioni Contenuti', - 'cms.contentsettings.titletip': 'Dalla sezione IMPOSTAZIONE CONTENUTI l\'amministratore può ricaricare le referenze e gli indici dei contenuti, selezionare l\'editor di testo e configurare il mapping dei metadata delle risorse con parametri degli attributi risorsa.', + 'cms.contentsettings.titletip': + "Dalla sezione IMPOSTAZIONE CONTENUTI l'amministratore può ricaricare le referenze e gli indici dei contenuti, selezionare l'editor di testo e configurare il mapping dei metadata delle risorse con parametri degli attributi risorsa.", 'cms.contentsettings.label.reloadreferences': 'Ricarica le referenze', 'cms.contentsettings.label.reloadindexes': 'Ricarica gli indici', 'cms.contentsettings.label.reloadstatus': 'Pronta', 'cms.contentsettings.label.reloadstatus.0': 'Pronta', 'cms.contentsettings.label.reloadstatus.1': 'Ricarico', 'cms.contentsettings.label.reloadstatus.2': 'Errore', - 'cms.contentsettings.label.reloadstatus.remark.success': 'L\'ultimo ricaricamento, in data {date}, ha avuto esisto positivo.', - 'cms.contentsettings.label.reloadstatus.remark.failed': 'L\'ultimo ricaricamento, in data {date}, ha avuto esisto negativo', - 'cms.contentsettings.cropvalueerror': 'Dimensioni di ritaglio non valide. Il formato deve essere "numero: numero"', - 'cms.contentsettings.cropratios.heading': 'Impostazioni Dimensioni di ritaglio immagine', - 'cms.contentsettings.cropratios.form.title': 'Aggiungi dimensione di ritaglio', - 'cms.contentsettings.ratio.added.success': 'Rapporto di ritaglio aggiunto correttamente', - 'cms.contentsettings.ratio.deleted.success': 'Rapporto di ritaglio eliminato correttamente', - 'cms.contentsettings.ratio.updated.success': 'Rapporto di ritaglio aggiornato correttamente', + 'cms.contentsettings.label.reloadstatus.remark.success': + "L'ultimo ricaricamento, in data {date}, ha avuto esisto positivo.", + 'cms.contentsettings.label.reloadstatus.remark.failed': + "L'ultimo ricaricamento, in data {date}, ha avuto esisto negativo", + 'cms.contentsettings.cropvalueerror': + 'Dimensioni di ritaglio non valide. Il formato deve essere "numero: numero"', + 'cms.contentsettings.cropratios.heading': + 'Impostazioni Dimensioni di ritaglio immagine', + 'cms.contentsettings.cropratios.form.title': + 'Aggiungi dimensione di ritaglio', + 'cms.contentsettings.ratio.added.success': + 'Rapporto di ritaglio aggiunto correttamente', + 'cms.contentsettings.ratio.deleted.success': + 'Rapporto di ritaglio eliminato correttamente', + 'cms.contentsettings.ratio.updated.success': + 'Rapporto di ritaglio aggiornato correttamente', 'cms.contentsettings.label.resourcemap': 'Resource Metadata Mapping', 'cms.contentsettings.form.addmetadata': 'Add Metadata', 'cms.contentsettings.form.key': 'Chiave', 'cms.contentsettings.form.mapping': 'Mapping', - 'cms.contentsettings.form.help': 'In questa sezione puoi aggiungere un nuovo metadata', + 'cms.contentsettings.form.help': + 'In questa sezione puoi aggiungere un nuovo metadata', 'cms.contentsettings.form.metadatamapping': 'Metadata Mapping', - 'cms.contentsettings.form.metadatamapping.help': 'Lista parametri (in CSV) delle relazioni tra Metadata Risorsa e Parametro "{key}" in fase di associazione risorsa immagine ad attributo contenuto', + 'cms.contentsettings.form.metadatamapping.help': + 'Lista parametri (in CSV) delle relazioni tra Metadata Risorsa e Parametro "{key}" in fase di associazione risorsa immagine ad attributo contenuto', 'cms.contentsettings.metadata.infoDeleted': '{name} rimosso', 'cms.new': 'Nuovo', 'cms.save': 'Salva', @@ -1247,7 +1485,7 @@ export default { 'cms.saveAndContinue': 'Salva e Continua', 'cms.setContentAs': 'Imposta contenuto come', 'cms.contents.notFound': 'Nessun contenuto trovato sul sistema.', - 'cms.chooseAnOption': 'Seleziona un\'opzione', + 'cms.chooseAnOption': "Seleziona un'opzione", 'cms.contents.contentStatus': 'Stato Contenuti', 'cms.contents.title': 'Contenuti', 'cms.contents.code': 'Codice', @@ -1260,36 +1498,46 @@ export default { 'cms.contents.edit.groups.ownerGroup.button': 'Imposta Gruppo', 'cms.contents.edit.groups.joinGroup.label': 'Unirsi al Gruppo', 'cms.contents.edit.categories': 'Categorie', - 'cms.contents.edit.groups.ownerGroup.tooltip': 'Dovresti impostare il gruppo principale in questo momento, altrimenti alcune cose diventeranno imprecise.', + 'cms.contents.edit.groups.ownerGroup.tooltip': + 'Dovresti impostare il gruppo principale in questo momento, altrimenti alcune cose diventeranno imprecise.', 'cms.contents.edit.tip': '* Campi richiesti', 'cms.contents.edit.contentType.label': 'Tipo di Contenuto', 'cms.contents.edit.contentDescription.label': 'Nome', - 'cms.contents.edit.contentDescription.tooltip': 'Fornisci un nome o userò il titolo se disponibile.', - 'cms.contents.edit.contentDescription.placeholder': 'I nomi ti aiutano ad archiviare, ordinare e trovare contenuti', + 'cms.contents.edit.contentDescription.tooltip': + 'Fornisci un nome o userò il titolo se disponibile.', + 'cms.contents.edit.contentDescription.placeholder': + 'I nomi ti aiutano ad archiviare, ordinare e trovare contenuti', 'cms.contents.edit.version.label': 'Versione', 'cms.contents.edit.version.creator': 'creato da', 'cms.contents.edit.version.modifier': 'modificato da', 'cms.contents.edit.duplicate': 'Copia in tutte le lingue', 'cms.contents.edit.label.duplicate': 'Contenuti duplicati', - 'cms.contents.edit.label.duplicateHelp': 'Copia e incolla il contenuto da questa scheda della lingua ad altri', + 'cms.contents.edit.label.duplicateHelp': + 'Copia e incolla il contenuto da questa scheda della lingua ad altri', 'cms.contents.edit.copytext': 'Copia Testo', 'cms.contents.edit.copiedSuccessfully': 'Contenuto copiato con successo.', 'cms.stickySave.lastAutoSave': 'Ultimo salvataggio: ', 'cms.content.status.unpublished': 'Non pubblicato', 'cms.content.status.unpublished.ready': 'Non pubblicato (pronto)', 'cms.content.status.pendingChanges': 'Pubblicato, con modifiche in sospeso', - 'cms.content.status.pendingChanges.publicNotEqualReady': 'Pubblicato, con modifiche in sospeso (pronto)', - 'cms.content.status.pendingChanges.publicNotEqualDraft': 'Pubblicato, con modifiche in sospeso', + 'cms.content.status.pendingChanges.publicNotEqualReady': + 'Pubblicato, con modifiche in sospeso (pronto)', + 'cms.content.status.pendingChanges.publicNotEqualDraft': + 'Pubblicato, con modifiche in sospeso', 'cms.content.status.published': 'Pubblicato', - 'cms.contents.edit.titletip': 'La sezione INDICE ti consente di gestire i contenuti esistenti, accedere all\'elenco dei contenuti, aggiungere nuovi contenuti. Puoi anche approvare, sospendere o eliminare i contenuti. In Entando, un contenuto è un elemento strutturato che rappresenta un insieme di informazioni costruite utilizzando gli attributi del contenuto.', + 'cms.contents.edit.titletip': + "La sezione INDICE ti consente di gestire i contenuti esistenti, accedere all'elenco dei contenuti, aggiungere nuovi contenuti. Puoi anche approvare, sospendere o eliminare i contenuti. In Entando, un contenuto è un elemento strutturato che rappresenta un insieme di informazioni costruite utilizzando gli attributi del contenuto.", 'cms.contents.edit.contentAttributes': 'Attributi del Contenuto', - 'cms.contents.edit.contentAttributes.language': 'Gli attributi possono essere modificati solo nella sezione della lingua predefinita', + 'cms.contents.edit.contentAttributes.language': + 'Gli attributi possono essere modificati solo nella sezione della lingua predefinita', 'cms.menu.contents': 'Gestione', 'cms.contents.list.all': 'Tutti', - 'cms.contents.tip': 'La sezione INDICE ti consente di gestire i contenuti esistenti, accedere all\'elenco dei contenuti, aggiungere nuovi contenuti. Puoi anche approvare, sospendere o eliminare i contenuti. In Entando, un contenuto è un elemento strutturato che rappresenta un insieme di informazioni costruite utilizzando gli attributi del contenuto.', + 'cms.contents.tip': + "La sezione INDICE ti consente di gestire i contenuti esistenti, accedere all'elenco dei contenuti, aggiungere nuovi contenuti. Puoi anche approvare, sospendere o eliminare i contenuti. In Entando, un contenuto è un elemento strutturato che rappresenta un insieme di informazioni costruite utilizzando gli attributi del contenuto.", 'cms.contents.quickSearchPlaceHolder': 'Cerca Contenuto', 'cms.contents.advancedFilters': 'Filtri Avanzati', - 'cms.contents.advancedFilters.invalidDatesRange': 'Intervallo di date non valido', + 'cms.contents.advancedFilters.invalidDatesRange': + 'Intervallo di date non valido', 'cms.contents.contentType': 'Tipo di Contenuto', 'cms.contents.group': 'Gruppo', 'cms.contents.statusMain': 'Stato', @@ -1307,16 +1555,18 @@ export default { 'cms.contents.search': 'Ricerca', 'cms.contents.onlyMine': 'Creati da me', 'cms.contents.pendingChanges': 'Modifiche in sospeso', - 'cms.contents.ready': 'Pronto per l\'approvazione', - 'cms.contents.readyPl': 'Pronti per l\'approvazione', + 'cms.contents.ready': "Pronto per l'approvazione", + 'cms.contents.readyPl': "Pronti per l'approvazione", 'cms.contents.rejected': 'Respinto', 'cms.contents.downloadAs': 'Scarica come', 'cms.contents.addContent': 'Aggiungi Contenuto', 'cms.contents.columns': 'Colonne', 'cms.contents.manageVersion': 'Gestisci Versioni', 'cms.contents.joinCategory': 'Unisciti alla categoria', - 'cms.contents.chooseJoiningCategories': 'Scegli le categorie a cui vuoi unirti al {number} contenuto selezionato!', - 'cms.contents.joinCategoriesTip': 'L\'azione cambierà la versione bozza dei contenuti selezionati, non la versione online. Per visualizzare le modifiche nella versione online, è necessario approvare le modifiche.', + 'cms.contents.chooseJoiningCategories': + 'Scegli le categorie a cui vuoi unirti al {number} contenuto selezionato!', + 'cms.contents.joinCategoriesTip': + "L'azione cambierà la versione bozza dei contenuti selezionati, non la versione online. Per visualizzare le modifiche nella versione online, è necessario approvare le modifiche.", 'cms.contents.seeOnlineVersion': 'Vedi Versione Online', 'cms.contents.change': 'Cambia contenuto', 'cms.contents.confirm': 'Conferma', @@ -1351,13 +1601,15 @@ export default { 'cms.contents.saved': 'Salvato', 'cms.contents.modal.filter.title': 'Seleziona un contenuto', 'cms.contents.modal.missingTranslations.title': 'Traduzioni mancanti', - 'cms.contents.modal.missingTranslations.content': 'Ci sono alcuni attributi con traduzioni mancanti.', + 'cms.contents.modal.missingTranslations.content': + 'Ci sono alcuni attributi con traduzioni mancanti.', 'cms.linkconfig.title': 'Configura il contenuto del collegamento', 'cms.linkconfig.attributes.heading': 'Attributi aggiuntivi', 'cms.linkconfig.pagetree': 'Pagine', 'cms.linkconfig.pageSelect': 'Scegli una pagina', 'cms.specialcharModal.title': 'Inserisci carattere speciale', - 'validateForm.name.help': 'Puoi inserire un massimo di 50 caratteri, lettere maiuscole e minuscole, numeri, ed i caratteri speciali', + 'validateForm.name.help': + 'Puoi inserire un massimo di 50 caratteri, lettere maiuscole e minuscole, numeri, ed i caratteri speciali', 'widget.form.sample': ' Modulo di esempio', 'widget.form.linkText': 'Link al testo', 'widget.form.text': 'Testo', @@ -1372,12 +1624,14 @@ export default { 'widget.form.maxElements': 'Max elementi totali', 'widget.form.default': 'Predefinito', 'widget.form.inclusiveOr': 'Usa filtro inclusivo (OR)', - 'widget.form.inclusiveOrTip': 'Se attivo, filtra i contenuti con un filtro inclusivo sulle categorie selezionate', + 'widget.form.inclusiveOrTip': + 'Se attivo, filtra i contenuti con un filtro inclusivo sulle categorie selezionate', 'widget.form.creationDate': 'Data di creazione', 'widget.form.lastModify': 'Ultima modifica', 'widget.form.asc': 'Ascendente', 'widget.form.desc': 'Discendente', - 'widget.form.extraOptionsDescription': 'Se lo desideri, puoi personalizzare il titolo del widget o aggiungere un collegamento a una pagina.', + 'widget.form.extraOptionsDescription': + 'Se lo desideri, puoi personalizzare il titolo del widget o aggiungere un collegamento a una pagina.', 'widget.form.remove': 'Rimuovi', 'widget.form.options': 'Opzioni', 'widget.form.settings': 'Impostazioni', @@ -1385,7 +1639,7 @@ export default { 'widget.form.reorder': 'Riordina', 'widget.form.selectFilter': 'Seleziona Filtro', 'widget.form.filteropt.creationDate': 'per data di creazione', - 'widget.form.filteropt.lastModify': 'dall\'ultima modifica', + 'widget.form.filteropt.lastModify': "dall'ultima modifica", 'widget.form.filterable.labelPresence': 'Filtra per presenza valore', 'widget.form.filterable.labelAbsence': 'Filtra per assenza di valore', 'widget.form.filterable.labelOnly': 'Filtra per valore', @@ -1397,9 +1651,12 @@ export default { 'widget.form.filterable.labelDateDelay': 'Ritardo (giorni)', 'widget.form.filterable.valuePresence': 'valore impostato', 'widget.form.filterable.valueAbsence': 'valore non impostato', - 'widget.form.filterable.valueOnly': 'che contiene: {value}', - 'widget.form.filterable.valuePartial': 'che contiene: {value} {partial}', - 'widget.form.filterable.valueDateDelay': ' con ritardo: {delay} giorni', + 'widget.form.filterable.valueOnly': + 'che contiene: {value}', + 'widget.form.filterable.valuePartial': + 'che contiene: {value} {partial}', + 'widget.form.filterable.valueDateDelay': + ' con ritardo: {delay} giorni', 'widget.form.filterable.valuePartialPhrase': '(corrispondenza parziale)', 'widget.form.filterable.valuePartialLabel': 'corrispondenza parziale', 'widget.form.filterable.valueRangeStart': 'de {start}', @@ -1413,14 +1670,18 @@ export default { 'contentPicker.allStatuses': 'Tutti', 'contentPicker.allTypes': 'Tutti', 'contentPicker.searchPlaceholder': 'Cerca un contenuto per nome o codice', - 'widget.warning.nodefaulttemplate.title': 'Modello di contenuto predefinito non trovato', - 'widget.warning.nodefaulttemplate.describe': 'Non esiste un modello di contenuto predefinito per questo tipo di contenuto. Seleziona un modello specifico o definisci un modello di contenuto predefinito per questo tipo.', - 'widget.warning.nodefaulttemplate.multidescribe': 'Uno dei tuoi contenuti non ha un modello di contenuto predefinito (elenco) del suo tipo di contenuto. Assicurati che tutti i tipi di contenuto dell\'elenco fornito abbiano almeno un modello di contenuto predefinito.', + 'widget.warning.nodefaulttemplate.title': + 'Modello di contenuto predefinito non trovato', + 'widget.warning.nodefaulttemplate.describe': + 'Non esiste un modello di contenuto predefinito per questo tipo di contenuto. Seleziona un modello specifico o definisci un modello di contenuto predefinito per questo tipo.', + 'widget.warning.nodefaulttemplate.multidescribe': + "Uno dei tuoi contenuti non ha un modello di contenuto predefinito (elenco) del suo tipo di contenuto. Assicurati che tutti i tipi di contenuto dell'elenco fornito abbiano almeno un modello di contenuto predefinito.", 'widget.singleContent.config.title': 'Singolo Contenuto', 'widget.singleContent.config.content': 'Contenuto', 'widget.singleContent.config.contentTemplate': 'Template di contenuto', 'widget.singleContent.config.changeContent': 'Cambia contenuto', - 'widget.singleContent.config.addExistingContent': 'Aggiungi contenuto esistente', + 'widget.singleContent.config.addExistingContent': + 'Aggiungi contenuto esistente', 'widget.singleContent.config.addNewContent': 'Aggiungi nuovi contenuti', 'widget.multipleContents.config.title': 'Elenco di Contenuti', 'widget.contentsQuery.config.title': 'Elenco dinamico di Contenuti', @@ -1570,14 +1831,16 @@ export default { 'hub.newRegistry': 'Nuovo Registro', 'hub.selectRegistry': 'Seleziona Registro', 'hub.localRegistry.title': 'Hub Locale', - 'hub.localRegistry.description': 'Questo è un hub locale in cui vengono visualizzati tutti i pacchetti distribuiti e i componenti ECR', + 'hub.localRegistry.description': + 'Questo è un hub locale in cui vengono visualizzati tutti i pacchetti distribuiti e i componenti ECR', 'hub.newRegistry.name': 'Nome', 'hub.newRegistry.url': 'URL', 'hub.newRegistry.apiKey': 'API Key', 'hub.newRegistry.name.error': 'Il nome del registro deve essere univoco', - 'hub.newRegistry.url.error': 'L\'URL del registro deve essere univoco', - 'hub.editRegistry.alert': 'Sottomettere questo modulo sostituirà l\'esistente API Key. Se non ne verrà inviata alcuna, quella precedente verrà eliminata.', - 'app.filterTypesSelect.organizationName': 'Nome dell\'organizzazione', + 'hub.newRegistry.url.error': "L'URL del registro deve essere univoco", + 'hub.editRegistry.alert': + "Sottomettere questo modulo sostituirà l'esistente API Key. Se non ne verrà inviata alcuna, quella precedente verrà eliminata.", + 'app.filterTypesSelect.organizationName': "Nome dell'organizzazione", 'app.filterTypesSelect.bundleGroup': 'Gruppo pacchetto', 'hub.bundle.installation': 'Installazione del pacchetto', 'hub.bundle.uninstallation': 'Disinstallazione del pacchetto', @@ -1602,19 +1865,31 @@ export default { 'componentRepository.categories.category': 'Categoria', 'componentRepository.categories.group': 'Gruppo', 'componentRepository.components.installedVersion': 'Versione installata', - 'componentRepository.components.genericError': 'Si è verificato un errore nell\'applicazione', - 'page.invalidChildPositionError': 'Una pagina appartenente ad un gruppo non può essere posizionata figlia della root', - 'page.invalidPositionError': 'Una pagina può essere figlia solo di un\'altra pagina con lo stesso owner group o con owner group free access', - 'app.installFailed': 'Si è verificato un errore e non è stato possibile installare il Bundle', - 'app.uninstallFailed': 'Si è verificato un errore e non è stato possibile disinstallare il Bundle', - 'app.fetchBundlesFailed': 'Non è stato possibile recuperare la lista di Bundle dal Registry', + 'componentRepository.components.genericError': + "Si è verificato un errore nell'applicazione", + 'page.invalidChildPositionError': + 'Una pagina appartenente ad un gruppo non può essere posizionata figlia della root', + 'page.invalidPositionError': + "Una pagina può essere figlia solo di un'altra pagina con lo stesso owner group o con owner group free access", + 'app.installFailed': + 'Si è verificato un errore e non è stato possibile installare il Bundle', + 'app.uninstallFailed': + 'Si è verificato un errore e non è stato possibile disinstallare il Bundle', + 'app.fetchBundlesFailed': + 'Non è stato possibile recuperare la lista di Bundle dal Registry', 'user.authority.addNew': 'Aggiungi nuova Autorizzazione', - 'componentRepository.refreshBundleVersions': 'Aggiorna le versioni disponibili del bundle', + 'componentRepository.refreshBundleVersions': + 'Aggiorna le versioni disponibili del bundle', 'componentRepository.bundle.installVersionsRefreshed': 'Aggiornato', - 'componentRepository.hub.epcInstalledTip': 'Per aggiornare il menu EPC, aggiorna la pagina di AppBuilder nel tuo browser', - 'ecr.componentUninstallError': 'Messaggio di errore: non è possibile disinstallare il {name}', - 'ecr.componentPartiallyDeleted': 'Alcuni elementi del bundle sono stati cancellati manualmente. Per disinstallare completamente il bundle e ripulire il sistema da ogni referenza interna, procedere con la disinstallazione.', - 'componentRepository.components.elementsUninstalled': 'Elementi Disinstallati', - 'componentRepository.components.someNotUninstalled': 'Alcuni elementi non sono stati disinstallati', + 'componentRepository.hub.epcInstalledTip': + 'Per aggiornare il menu EPC, aggiorna la pagina di AppBuilder nel tuo browser', + 'ecr.componentUninstallError': + 'Messaggio di errore: non è possibile disinstallare il {name}', + 'ecr.componentPartiallyDeleted': + 'Alcuni elementi del bundle sono stati cancellati manualmente. Per disinstallare completamente il bundle e ripulire il sistema da ogni referenza interna, procedere con la disinstallazione.', + 'componentRepository.components.elementsUninstalled': + 'Elementi Disinstallati', + 'componentRepository.components.someNotUninstalled': + 'Alcuni elementi non sono stati disinstallati', }, }; diff --git a/src/locales/pt.js b/src/locales/pt.js index 5c9fd69bb..572c6c6a2 100644 --- a/src/locales/pt.js +++ b/src/locales/pt.js @@ -450,6 +450,7 @@ export default { 'fileBrowser.createFolder': 'Criar pasta', 'fileBrowser.uploadFiles': 'Upload Files', 'fileBrowser.uploadFileComplete': 'Upload de arquivo concluído', + 'fileBrowser.removeFileComplete': 'Remover arquivo concluído', 'fileBrowser.uploadFileError': 'Erro no upload de arquivo - {errmsg}', 'fileBrowser.downloadFile': 'Download', 'fileBrowser.newFolder': 'Nova da Nova Pasta', diff --git a/src/state/avatar/actions.js b/src/state/avatar/actions.js new file mode 100644 index 000000000..f332e7cb2 --- /dev/null +++ b/src/state/avatar/actions.js @@ -0,0 +1,105 @@ +import { postAvatar, getAvatar, deleteAvatar } from 'api/avatar'; +import { getBase64 } from 'state/file-browser/actions'; +import { toggleLoading } from 'state/loading/actions'; +import { addToast, addErrors, TOAST_SUCCESS, TOAST_ERROR } from '@entando/messages'; +import { SET_AVATAR_FILE_NAME, SET_USE_GRAVATAR } from './types'; + +export const setAvatarFilename = filename => ({ + type: SET_AVATAR_FILE_NAME, + payload: { + filename, + }, +}); + +export const setUseGravatar = useGravatar => ({ + type: SET_USE_GRAVATAR, + payload: { + useGravatar, + }, +}); + + +export const createFileObject = async (avatar) => { + const base64 = await getBase64(avatar); + return { filename: avatar.name, base64 }; +}; + +export const uploadAvatar = + (avatar, loader = 'uploadAvatar') => + async (dispatch) => { + try { + dispatch(toggleLoading(loader)); + const requestObject = await createFileObject(avatar); + const response = await postAvatar(requestObject); + const { payload } = await response.json(); + const { filename } = payload; + dispatch(setUseGravatar(false)); + dispatch(setAvatarFilename(`${filename}?${Date.now()}`)); + dispatch(toggleLoading(loader)); + dispatch(addToast({ id: 'fileBrowser.uploadFileComplete' }, TOAST_SUCCESS)); + } catch (error) { + dispatch(toggleLoading(loader)); + const message = { id: 'fileBrowser.uploadFileError', values: { errmsg: error } }; + dispatch(addErrors(error)); + dispatch(addToast(message, TOAST_ERROR)); + } + }; + +export const setGravatar = (loader = 'useGravatar') => + async (dispatch) => { + try { + dispatch(toggleLoading(loader)); + const response = await postAvatar({ useGravatar: true }); + const { payload } = await response.json(); + const { useGravatar } = payload; + dispatch(setUseGravatar(useGravatar)); + dispatch(addToast({ id: 'fileBrowser.uploadFileComplete' }, TOAST_SUCCESS)); + dispatch(toggleLoading(loader)); + } catch (error) { + dispatch(toggleLoading(loader)); + const message = { id: 'fileBrowser.uploadFileError', values: { errmsg: error } }; + dispatch(addErrors(error)); + dispatch(addToast(message, TOAST_ERROR)); + } + }; + +export const fetchAvatar = (loader = 'fetchAvatar') => async (dispatch) => { + try { + dispatch(toggleLoading(loader)); + const response = await getAvatar(); + const { ok, status } = response; + if (ok) { + const { payload } = await response.json(); + const { filename, useGravatar } = payload; + dispatch(setUseGravatar(useGravatar)); + if (filename) dispatch(setAvatarFilename(`${filename}?${Date.now()}`)); + } else if (!ok && status === 404) { + dispatch(setUseGravatar(false)); + dispatch(setAvatarFilename('')); + } + dispatch(toggleLoading(loader)); + } catch (error) { + dispatch(toggleLoading(loader)); + dispatch(addErrors(error)); + dispatch(addToast(error.message, TOAST_ERROR)); + } +}; + + +export const removeAvatar = + (loader = 'removeAvatar') => + async (dispatch) => { + try { + dispatch(toggleLoading(loader)); + await deleteAvatar(); + dispatch(setAvatarFilename('')); + dispatch(setUseGravatar(false)); + dispatch(toggleLoading(loader)); + dispatch(addToast({ id: 'fileBrowser.removeFileComplete' }, TOAST_SUCCESS)); + } catch (error) { + dispatch(toggleLoading(loader)); + const message = { id: 'fileBrowser.uploadFileError', values: { errmsg: error } }; + dispatch(addErrors(error)); + dispatch(addToast(message, TOAST_ERROR)); + } + }; diff --git a/src/state/avatar/reducer.js b/src/state/avatar/reducer.js new file mode 100644 index 000000000..875bb1d72 --- /dev/null +++ b/src/state/avatar/reducer.js @@ -0,0 +1,33 @@ +import { combineReducers } from 'redux'; +import { SET_AVATAR_FILE_NAME, SET_USE_GRAVATAR } from './types'; + +const initialState = { + filename: '', + useGravatar: false, +}; + +const filename = (state = initialState.filename, action = {}) => { + switch (action.type) { + case SET_AVATAR_FILE_NAME: { + return action.payload.filename; + } + default: + return state; + } +}; + +const useGravatar = (state = initialState.useGravatar, action = {}) => { + switch (action.type) { + case SET_USE_GRAVATAR: { + return action.payload.useGravatar; + } + default: + return state; + } +}; + +export default combineReducers({ + filename, + useGravatar, +}); + diff --git a/src/state/avatar/selectors.js b/src/state/avatar/selectors.js new file mode 100644 index 000000000..5ec68cb1b --- /dev/null +++ b/src/state/avatar/selectors.js @@ -0,0 +1,14 @@ +import { createSelector } from 'reselect'; + +export const getAvatar = state => state.avatar; + +export const getAvatarFilename = createSelector( + getAvatar, + avatar => avatar.filename, +); + +export const getUseGravatar = createSelector( + getAvatar, + avatar => avatar.useGravatar, +); + diff --git a/src/state/avatar/types.js b/src/state/avatar/types.js new file mode 100644 index 000000000..4262e955f --- /dev/null +++ b/src/state/avatar/types.js @@ -0,0 +1,3 @@ +export const SET_AVATAR_FILE_NAME = 'avatar/filename'; +export const SET_USE_GRAVATAR = 'avatar/useGravatar'; + diff --git a/src/state/file-browser/actions.js b/src/state/file-browser/actions.js index fbd8b8c73..4d7555877 100644 --- a/src/state/file-browser/actions.js +++ b/src/state/file-browser/actions.js @@ -34,7 +34,7 @@ const wrapApiCall = apiFunc => (...args) => async (dispatch) => { // thunks -const getBase64 = file => ( +export const getBase64 = file => ( new Promise((resolve) => { const reader = new FileReader(); reader.readAsDataURL(file); diff --git a/src/state/page-templates/helpers.js b/src/state/page-templates/helpers.js index 45cc1d82a..1dfcff445 100644 --- a/src/state/page-templates/helpers.js +++ b/src/state/page-templates/helpers.js @@ -222,7 +222,12 @@ const fixMissingSketch = (frames) => { }; export const getCellMap = (pageTemplate) => { - if (!pageTemplate || !pageTemplate.configuration || !pageTemplate.configuration.frames) { + if ( + !pageTemplate || + !pageTemplate.configuration || + !pageTemplate.configuration.frames || + !pageTemplate.configuration.frames.length + ) { return null; } const errors = validatePageTemplate(pageTemplate); diff --git a/src/state/profile-types/actions.js b/src/state/profile-types/actions.js index 06bf20685..41208a97c 100644 --- a/src/state/profile-types/actions.js +++ b/src/state/profile-types/actions.js @@ -79,6 +79,7 @@ import { MODE_ADD_MONOLIST_ATTRIBUTE_COMPOSITE, MODE_ADD_SUB_ATTRIBUTE_MONOLIST_COMPOSITE, } from 'state/profile-types/const'; +import { TYPE_ENUMERATOR, TYPE_ENUMERATOR_MAP } from 'state/content-type/const'; // Profile type export const setProfileTypes = profileTypes => ({ @@ -486,6 +487,7 @@ export const sendDeleteAttributeFromProfileType = attributeCode => (dispatch, ge }) ); +export const excludeTypes = [TYPE_COMPOSITE, TYPE_LIST, TYPE_ENUMERATOR, TYPE_ENUMERATOR_MAP]; export const fetchProfileTypeAttributes = (page = { page: 1, pageSize: 0 }, params = '') => (dispatch, getState) => ( new Promise((resolve) => { @@ -495,7 +497,9 @@ export const fetchProfileTypeAttributes = (page = { page: 1, pageSize: 0 }, para if (response.ok) { const list = getProfileTypeAttributesIdList(getState()); if (!list || list.length === 0) { - dispatch(setProfileTypeAttributes(json.payload)); + const exludedAttributes = json.payload ? + json.payload.filter(attribute => !excludeTypes.includes(attribute)) : []; + dispatch(setProfileTypeAttributes(exludedAttributes)); } } else { dispatch(addErrors(json.errors.map(err => err.message))); diff --git a/src/state/profile-types/selectors.js b/src/state/profile-types/selectors.js index bcee9571a..f24e777cb 100644 --- a/src/state/profile-types/selectors.js +++ b/src/state/profile-types/selectors.js @@ -6,6 +6,7 @@ import { TYPE_LIST, TYPE_COMPOSITE, } from 'state/profile-types/const'; +import { getUserProfile } from 'state/user-profile/selectors'; const NO_ATTRIBUTE_FOR_TYPE_MONOLIST = [TYPE_LIST, TYPE_MONOLIST]; @@ -180,3 +181,15 @@ export const getProfileTypeReferencesStatus = createSelector([getProfileTypeRefe } return { type: 'success', status: 'ready', profileTypesCode: [] }; }); + +export const getUserProfileEmail = createSelector( + [getSelectedProfileTypeAttributes, getUserProfile], + (selectedUserProfileAttributes, userProfile) => { + const emailAttribute = selectedUserProfileAttributes + && selectedUserProfileAttributes.find(attribute => attribute.roles && attribute.roles.find(role => role.code === 'userprofile:email')); + const { attributes } = userProfile; + const userProfileEmailAttribute = + attributes.find(attr => emailAttribute && attr.code === emailAttribute.code); + return userProfileEmailAttribute && userProfileEmailAttribute.value; + }, +); diff --git a/src/state/rootReducer.js b/src/state/rootReducer.js index 2b52b0217..9b91b1b1a 100644 --- a/src/state/rootReducer.js +++ b/src/state/rootReducer.js @@ -44,7 +44,7 @@ import editContent from 'state/edit-content/reducer'; import contents from 'state/contents/reducer'; import system from 'state/system/reducer'; import currentTenant from 'state/multi-tenancy/reducer'; - +import avatar from 'state/avatar/reducer'; import entandoApps from 'entando-apps'; import hub from 'state/component-repository/hub/reducer'; import mfe from 'state/mfe/reducer'; @@ -103,6 +103,7 @@ const reducerDef = { mfe, currentTenant, currentSystemConfiguration, + avatar, }; // app root reducer diff --git a/src/state/user-profile/selectors.js b/src/state/user-profile/selectors.js index f9480c93a..26c0a83fd 100644 --- a/src/state/user-profile/selectors.js +++ b/src/state/user-profile/selectors.js @@ -2,6 +2,6 @@ export const getUserProfile = state => state.userProfile; export const getUserEmail = (state) => { const { attributes } = state.userProfile; - const emailAttribute = attributes.find(attr => attr.code === 'email'); + const emailAttribute = attributes && attributes.find(attr => attr.code === 'email'); return emailAttribute && emailAttribute.value; }; diff --git a/src/ui/common/Button.js b/src/ui/common/Button.js new file mode 100644 index 000000000..29a180e92 --- /dev/null +++ b/src/ui/common/Button.js @@ -0,0 +1,25 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import cx from 'classnames'; +import { Button as PatternFlyButton } from 'patternfly-react'; + +const Button = ({ + children, className, ...props +}) => ( + {children} +); + +Button.propTypes = { + children: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.node, + ]).isRequired, + className: PropTypes.string, +}; + +Button.defaultProps = { + className: '', +}; + + +export default Button; diff --git a/src/ui/common/CardItem.js b/src/ui/common/CardItem.js new file mode 100644 index 000000000..b8b8f8bcb --- /dev/null +++ b/src/ui/common/CardItem.js @@ -0,0 +1,69 @@ +/* eslint-disable react/require-default-props */ +import React from 'react'; +import PropTypes from 'prop-types'; +import { OverlayTrigger, Popover } from 'patternfly-react'; +import { FormattedMessage } from 'react-intl'; +import { withPermissionValues } from 'ui/auth/withPermissions'; +import WidgetIcon from 'ui/widgets/common/WidgetIcon'; +import { routeConverter } from '@entando/utils'; +import { Link } from 'react-router-dom'; + +const CardItem = ({ + title, + code, + subtitle, + description, + used, + actions, + route, +}) => ( +
+ {actions &&
{actions}
} +
+ +
+
+
+ {route ? + + {title} + : +
+ {title} +
+ } + {used && + + + + } + > +
{used}
+
+ } +
+
{subtitle}
+ {description &&
{description}
} +
+
+); + +CardItem.propTypes = { + title: PropTypes.string.isRequired, + code: PropTypes.string.isRequired, + subtitle: PropTypes.string, + description: PropTypes.string, + used: PropTypes.number, + actions: PropTypes.func, + route: PropTypes.shape({ + url: PropTypes.string.isRequired, + type: PropTypes.string.isRequired, + }), +}; + +export default withPermissionValues(CardItem); diff --git a/src/ui/common/CardList.js b/src/ui/common/CardList.js new file mode 100644 index 000000000..1bdc32061 --- /dev/null +++ b/src/ui/common/CardList.js @@ -0,0 +1,38 @@ +/* eslint-disable react/require-default-props */ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withPermissionValues } from 'ui/auth/withPermissions'; +import CardItem from 'ui/common/CardItem'; + +const CardList = ({ list, actions, route }) => + ( +
+ {list.map(item => ( + + ))} +
+ ); +CardList.propTypes = { + list: PropTypes.arrayOf(PropTypes.shape({ + title: PropTypes.string.isRequired, + code: PropTypes.string.isRequired, + subtitle: PropTypes.string, + used: PropTypes.number, + })).isRequired, + actions: PropTypes.func, + route: PropTypes.shape({ + url: PropTypes.string.isRequired, + type: PropTypes.string.isRequired, + }), +}; + +export default withPermissionValues(CardList); diff --git a/src/ui/common/Search.js b/src/ui/common/Search.js new file mode 100644 index 000000000..7d6d0205e --- /dev/null +++ b/src/ui/common/Search.js @@ -0,0 +1,12 @@ +import React from 'react'; +import Icon from './icon/Icon'; + +// eslint-disable-next-line react/prop-types +const Search = ({ input, reverse, ...rest }) => ( +
+ + +
+); + +export default Search; diff --git a/src/ui/common/dropdown-button/DropdownButton.js b/src/ui/common/dropdown-button/DropdownButton.js new file mode 100644 index 000000000..3d9784428 --- /dev/null +++ b/src/ui/common/dropdown-button/DropdownButton.js @@ -0,0 +1,30 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { intlShape } from 'react-intl'; +import { DropdownButton as PatternflyDropButton } from 'patternfly-react'; +import MenuItem from './MenuItem'; + +const DropdownButton = ({ + options, intl, onSelect, ...rest +}) => ( + + {options.map(option => ( + ))} + ); + +DropdownButton.propTypes = { + options: PropTypes.arrayOf(PropTypes.shape({ + value: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + })).isRequired, + intl: intlShape.isRequired, + onSelect: PropTypes.func.isRequired, +}; + +export default DropdownButton; diff --git a/src/ui/common/dropdown-button/MenuItem.js b/src/ui/common/dropdown-button/MenuItem.js new file mode 100644 index 000000000..58a409dcd --- /dev/null +++ b/src/ui/common/dropdown-button/MenuItem.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { MenuItem as PatternflyMenuItem } from 'patternfly-react'; +import PropTypes from 'prop-types'; + +const MenuItem = ({ label, ...rest }) => ( + + {label} + +); + +MenuItem.propTypes = { + label: PropTypes.string, +}; + +MenuItem.defaultProps = { + label: 'search', +}; + + +export default MenuItem; diff --git a/src/ui/common/form/RenderSearchFormInput.js b/src/ui/common/form/RenderSearchFormInput.js index dcbcd77ee..eb347fa56 100644 --- a/src/ui/common/form/RenderSearchFormInput.js +++ b/src/ui/common/form/RenderSearchFormInput.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl, intlShape } from 'react-intl'; +import cx from 'classnames'; import { Button, Icon } from 'patternfly-react'; const msgs = defineMessages({ @@ -26,14 +27,12 @@ const RenderSearchFormInput = ({ placeholder={intl.formatMessage(msgs.search)} {...others} /> - {input.value ? ( - - ) : null} + ); diff --git a/src/ui/common/icon/Icon.js b/src/ui/common/icon/Icon.js new file mode 100644 index 000000000..50d1df95f --- /dev/null +++ b/src/ui/common/icon/Icon.js @@ -0,0 +1,31 @@ +/* eslint-disable react/prop-types, no-case-declarations */ +import React from 'react'; +import cx from 'classnames'; +import { Icon as PFIcon } from 'patternfly-react'; +import IconMap from 'ui/common/icon/IconMap'; + +const publicUrl = process.env.PUBLIC_URL; + +const Icon = ({ + background, type = 'patternfly-icon', ...props +}) => { + switch (type) { + case ('svg'): + return {props.alt}; + case ('lucide'): + const LucideIcon = IconMap[props.name]; + return ( +
+ +
+ ); + default: + return (); + } +}; + +export default Icon; diff --git a/src/ui/common/icon/IconMap.js b/src/ui/common/icon/IconMap.js new file mode 100644 index 000000000..4b5ea354c --- /dev/null +++ b/src/ui/common/icon/IconMap.js @@ -0,0 +1,19 @@ +import { Users, Flag, Grid2x2Plus, Copy, AlignLeft, Plus, Pencil, Trash2, Box, Info, Play, Undo, Globe, Layers, Component } from 'lucide-react'; + +export default { + users: Users, + flag: Flag, + components: Grid2x2Plus, + pages: Copy, + text: AlignLeft, + plus: Plus, + pencil: Pencil, + bin: Trash2, + box: Box, + info: Info, + play: Play, + undo: Undo, + globe: Globe, + system: Layers, + cms: Component, +}; diff --git a/src/ui/component-repository/CategoryFilter.js b/src/ui/component-repository/CategoryFilter.js index a528b5b76..b84c7ea7a 100644 --- a/src/ui/component-repository/CategoryFilter.js +++ b/src/ui/component-repository/CategoryFilter.js @@ -2,25 +2,30 @@ import React from 'react'; import PropTypes from 'prop-types'; import { injectIntl, intlShape } from 'react-intl'; import { reduxForm } from 'redux-form'; +import { DropdownButton } from 'patternfly-react'; import CheckboxGroup from 'ui/component-repository/common/CheckboxGroup'; -import SidebarFilter from 'ui/component-repository/common/SidebarFilter'; - -const CategoryFilterBody = ({ componentRepositoryCategories, intl, onChange }) => ( - - - -); +const CategoryFilterBody = ({ + componentRepositoryCategories, intl, onChange, showCategoryFilter, +}) => ( + showCategoryFilter ? + + + + : ); CategoryFilterBody.propTypes = { intl: intlShape.isRequired, componentRepositoryCategories: PropTypes.arrayOf(PropTypes.shape({})).isRequired, onChange: PropTypes.func.isRequired, + showCategoryFilter: PropTypes.bool.isRequired, }; export default reduxForm({ diff --git a/src/ui/component-repository/CategoryFilterContainer.js b/src/ui/component-repository/CategoryFilterContainer.js index d62f81f7a..f1c261196 100644 --- a/src/ui/component-repository/CategoryFilterContainer.js +++ b/src/ui/component-repository/CategoryFilterContainer.js @@ -1,5 +1,6 @@ import { connect } from 'react-redux'; import { injectIntl } from 'react-intl'; +import { isAllCategoriesCategorySelected } from 'state/component-repository/categories/selectors'; import { getECRCategoryFilters } from 'state/component-repository/components/selectors'; import { filterByECRCategories } from 'state/component-repository/actions'; import CategoryFilter from 'ui/component-repository/CategoryFilter'; @@ -16,6 +17,7 @@ export const mapDispatchToProps = dispatch => ({ }); export const mapStateToProps = (state, { intl }) => ({ + showCategoryFilter: isAllCategoriesCategorySelected(state), componentRepositoryCategories: generateCRCategoryObjects(COMPONENT_REPOSITORY_CATEGORIES, intl), initialValues: { categories: getECRCategoryFilters(state) }, }); diff --git a/src/ui/component-repository/Sidebar.js b/src/ui/component-repository/Sidebar.js index aa3051daa..2c5b15dd3 100644 --- a/src/ui/component-repository/Sidebar.js +++ b/src/ui/component-repository/Sidebar.js @@ -1,15 +1,15 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import CategoryFilterContainer from 'ui/component-repository/CategoryFilterContainer'; +// import React from 'react'; +// import PropTypes from 'prop-types'; +// import CategoryFilterContainer from 'ui/component-repository/CategoryFilterContainer'; -const Sidebar = ({ showCategoryFilter }) => ( -
- { showCategoryFilter ? : '' } -
-); +// const Sidebar = ({ showCategoryFilter }) => ( +//
+// { showCategoryFilter ? : '' } +//
+// ); -Sidebar.propTypes = { - showCategoryFilter: PropTypes.bool.isRequired, -}; +// Sidebar.propTypes = { +// showCategoryFilter: PropTypes.bool.isRequired, +// }; -export default Sidebar; +// export default Sidebar; diff --git a/src/ui/component-repository/SidebarContainer.js b/src/ui/component-repository/SidebarContainer.js index a6e1ef48c..de9741848 100644 --- a/src/ui/component-repository/SidebarContainer.js +++ b/src/ui/component-repository/SidebarContainer.js @@ -1,16 +1,16 @@ -import { connect } from 'react-redux'; -import { isAllCategoriesCategorySelected } from 'state/component-repository/categories/selectors'; -import Sidebar from 'ui/component-repository/Sidebar'; +// import { connect } from 'react-redux'; -const mapDispatchToProps = null; +// import Sidebar from 'ui/component-repository/Sidebar'; -export const mapStateToProps = state => ({ - showCategoryFilter: isAllCategoriesCategorySelected(state), -}); +// const mapDispatchToProps = null; -const SidebarContainer = connect( - mapStateToProps, - mapDispatchToProps, -)(Sidebar); +// export const mapStateToProps = state => ({ +// showCategoryFilter: isAllCategoriesCategorySelected(state), +// }); -export default SidebarContainer; +// const SidebarContainer = connect( +// mapStateToProps, +// mapDispatchToProps, +// )(Sidebar); + +// export default SidebarContainer; diff --git a/src/ui/component-repository/common/SidebarFilter.js b/src/ui/component-repository/common/SidebarFilter.js index 5c77731ac..2354268db 100644 --- a/src/ui/component-repository/common/SidebarFilter.js +++ b/src/ui/component-repository/common/SidebarFilter.js @@ -1,21 +1,21 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +// import React from 'react'; +// import PropTypes from 'prop-types'; -const SidebarFilter = ({ title, children }) => ( -
-
- {title} -
-
- { children } -
-
-); +// const SidebarFilter = ({ title, children }) => ( +//
+//
+// {title} +//
+//
+// { children } +//
+//
+// ); -SidebarFilter.propTypes = { - title: PropTypes.string.isRequired, - children: PropTypes.node.isRequired, -}; +// SidebarFilter.propTypes = { +// title: PropTypes.string.isRequired, +// children: PropTypes.node.isRequired, +// }; -export default SidebarFilter; +// export default SidebarFilter; diff --git a/src/ui/component-repository/common/TabBarFilter.js b/src/ui/component-repository/common/TabBarFilter.js index fda055443..2d014df80 100644 --- a/src/ui/component-repository/common/TabBarFilter.js +++ b/src/ui/component-repository/common/TabBarFilter.js @@ -31,7 +31,7 @@ class TabBarFilter extends Component { return (
- : +
{ > -
-
+ ) + } + {isLocalRegistry ? : } +
+ { isLocalRegistry && () } +
+ { isLocalRegistry && } +
+
+ +
+ { !isLocalRegistry && ( + + ) + } + + + + + ); +}; + +export default ComponentListActionsWrapper; diff --git a/src/ui/component-repository/components/list/ComponentListGridView.js b/src/ui/component-repository/components/list/ComponentListGridView.js index 84fe9f8c1..1254bb08a 100644 --- a/src/ui/component-repository/components/list/ComponentListGridView.js +++ b/src/ui/component-repository/components/list/ComponentListGridView.js @@ -43,7 +43,6 @@ const ComponentListGridView =
openComponentManagementModal(component)} @@ -59,6 +58,16 @@ const ComponentListGridView = }

{component.title}

+

{component.description}

+ + +
+
+ { component.installed &&
@@ -77,16 +86,6 @@ const ComponentListGridView =
} -

{component.description}

- - -
-
-
diff --git a/src/ui/component-repository/components/list/ComponentListListView.js b/src/ui/component-repository/components/list/ComponentListListView.js index 4d4aa9817..ed9e43af4 100644 --- a/src/ui/component-repository/components/list/ComponentListListView.js +++ b/src/ui/component-repository/components/list/ComponentListListView.js @@ -33,7 +33,7 @@ const ComponentListListView = > -
+

{component.title}

+

{component.description}

+ + +
+
+ { component.installed &&
@@ -69,16 +79,6 @@ const ComponentListListView =
} -

{component.description}

- - -
-
-
diff --git a/src/ui/component-repository/components/list/ComponentListPage.js b/src/ui/component-repository/components/list/ComponentListPage.js index ba3356474..b90dd7ca2 100644 --- a/src/ui/component-repository/components/list/ComponentListPage.js +++ b/src/ui/component-repository/components/list/ComponentListPage.js @@ -1,47 +1,58 @@ import React from 'react'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; +import { useSelector } from 'react-redux'; +import { Grid } from 'patternfly-react'; +import { getSelectedRegistry } from 'state/component-repository/hub/selectors'; +import { ECR_LOCAL_REGISTRY_NAME } from 'state/component-repository/hub/reducer'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import withPermissions from 'ui/auth/withPermissions'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; -import { FormattedMessage } from 'react-intl'; import { ENTER_ECR_PERMISSION, SUPERUSER_PERMISSION } from 'state/permissions/const'; import { ROUTE_ECR_COMPONENT_LIST, ROUTE_ECR_CONFIG_LIST } from 'app-init/router'; import InstallationPlanModal from 'ui/component-repository/components/InstallationPlanModal'; -import ComponentListWrapper from 'ui/component-repository/components/list/ComponentListWrapper'; import AddNewRegistryModal from 'ui/component-repository/components/list/AddNewRegistryModal'; import DeleteRegistryModalContainer from 'ui/component-repository/components/list/DeleteRegistryModalContainer'; import EditRegistryModal from 'ui/component-repository/components/list/EditRegistryModal'; import ComponentUninstallManagerModal from 'ui/component-repository/components/item/install-controls/ComponentUninstallManagerModal'; +import HubBundleList from 'ui/component-repository/components/list/HubBundleList'; +import ComponentListActionsWrapper from './ComponentListActionsWrapper'; +import ComponentListContainer from './ComponentListContainer'; +import HubRegistrySwitcher from './HubRegistrySwitcher'; -export const ComponentListPageBody = () => ( - - -
- - - - - - - - - - -
- -
- - - - - -
-); + +export const ComponentListPageBody = () => { + const activeRegistry = useSelector(getSelectedRegistry); + const isLocalRegistry = activeRegistry.name === ECR_LOCAL_REGISTRY_NAME; + + return ( + + + +
+ + + +
+
+ + { isLocalRegistry ? : } +
+
+ + + + + +
+ ); +}; export default withPermissions([SUPERUSER_PERMISSION, ENTER_ECR_PERMISSION])(ComponentListPageBody); diff --git a/src/ui/component-repository/components/list/ComponentListViewModeSwitcherContainer.js b/src/ui/component-repository/components/list/ComponentListViewModeSwitcherContainer.js index 8d1468b6d..961df2be4 100644 --- a/src/ui/component-repository/components/list/ComponentListViewModeSwitcherContainer.js +++ b/src/ui/component-repository/components/list/ComponentListViewModeSwitcherContainer.js @@ -2,8 +2,11 @@ import React from 'react'; import { connect } from 'react-redux'; import { setECRComponentListViewMode } from 'state/component-repository/components/actions'; import { getECRComponentListViewMode } from 'state/component-repository/components/selectors'; +import { FormattedMessage } from 'react-intl'; import PropTypes from 'prop-types'; import { ECR_COMPONENTS_GRID_VIEW, ECR_COMPONENTS_LIST_VIEW } from 'state/component-repository/components/const'; +import Button from 'ui/common/Button'; +import { ButtonGroup } from 'patternfly-react'; const ComponentListViewModeSwitcher = ({ viewMode, changeViewMode }) => { @@ -17,23 +20,26 @@ const ComponentListViewModeSwitcher = ({ viewMode, changeViewMode }) => { changeViewMode(ECR_COMPONENTS_LIST_VIEW); }; - const selectedClass = 'ComponentListViewModeSwitcher__btn--selected'; + const selectedClass = 'ComponentListViewModeSwitcher__btn--selected active'; const btnClass = 'ComponentListViewModeSwitcher__btn'; return (
- - + + + + +
); }; diff --git a/src/ui/component-repository/components/list/HubBundleList.js b/src/ui/component-repository/components/list/HubBundleList.js index e719d2b7d..8424dd7db 100644 --- a/src/ui/component-repository/components/list/HubBundleList.js +++ b/src/ui/component-repository/components/list/HubBundleList.js @@ -98,20 +98,20 @@ const HubBundleList = ({ ), {}); return ( -
- + +
{components} - - {openedModal === HUB_BUNDLE_MANAGEMENT_MODAL_ID && } - -
+
+ + {openedModal === HUB_BUNDLE_MANAGEMENT_MODAL_ID && } + ); }; diff --git a/src/ui/component-repository/components/list/HubRegistrySwitcher.js b/src/ui/component-repository/components/list/HubRegistrySwitcher.js index 3f3a7ffd1..b764e3656 100644 --- a/src/ui/component-repository/components/list/HubRegistrySwitcher.js +++ b/src/ui/component-repository/components/list/HubRegistrySwitcher.js @@ -65,81 +65,84 @@ const HubRegistrySwitcher = () => { return ( -
-
-
- {activeRegistry.name} -
-
- {activeRegistry.url} -
-
-
-
- +
+
+
+
+ {activeRegistry.name} +
+
-
- - { - registries.map(reg => ( - -
handleRegistryChange(reg)} - onKeyDown={() => handleDeleteRegistry(reg)} - className="HubRegistrySwitcher__action-label" +
+
+ +
+
+ + { + registries.map(reg => ( + - - {reg.name} -
- { - reg.name !== ECR_LOCAL_REGISTRY_NAME && ( - -
handleEditRegistry(reg)} - onKeyDown={() => handleEditRegistry(reg)} - > - -
-
handleDeleteRegistry(reg)} - onKeyDown={() => handleDeleteRegistry(reg)} - > - -
-
- ) - } - - )) - } - -
- -
-
- +
handleRegistryChange(reg)} + onKeyDown={() => handleDeleteRegistry(reg)} + className="HubRegistrySwitcher__action-label" + > + + {reg.name} +
+ { + reg.name !== ECR_LOCAL_REGISTRY_NAME && ( + +
handleEditRegistry(reg)} + onKeyDown={() => handleEditRegistry(reg)} + > + +
+
handleDeleteRegistry(reg)} + onKeyDown={() => handleDeleteRegistry(reg)} + > + +
+
+ ) + } + + )) + } + +
+ +
+
+ +
+
+ {activeRegistry.url} +
diff --git a/src/ui/contents/list-card/ContentListCard.js b/src/ui/contents/list-card/ContentListCard.js index 41ab44134..7c6b7d279 100644 --- a/src/ui/contents/list-card/ContentListCard.js +++ b/src/ui/contents/list-card/ContentListCard.js @@ -17,6 +17,8 @@ import { import ViewPermissionNoticeOverlay from 'ui/dashboard/ViewPermissionNoticeOverlay'; import paginatorMessages from 'ui/common/paginatorMessages'; +import Icon from 'ui/common/icon/Icon'; +import StatusBadge from 'ui/pages/common/StatusBadge'; class ContentListCard extends Component { constructor(props) { @@ -27,13 +29,10 @@ class ContentListCard extends Component { componentDidMount() { const { - onDidMount, - columnOrder, - onSetColumnOrder, - userPermissions, + onDidMount, columnOrder, onSetColumnOrder, userPermissions, } = this.props; if (!columnOrder.length) { - onSetColumnOrder(['description', 'lastEditor', 'typeDescription', 'status', 'lastModified']); + onSetColumnOrder(['description', 'typeDescription', 'status', 'lastModified']); } if (hasAccess(ADMINISTRATION_AREA_PERMISSION, userPermissions)) { onDidMount(); @@ -53,12 +52,7 @@ class ContentListCard extends Component { className: 'SingleContentCurrentVersion__description', }, }, - lastEditor: { - Header: , - attributes: { - style: { width: '13%' }, - }, - }, + typeDescription: { Header: , attributes: { @@ -68,14 +62,20 @@ class ContentListCard extends Component { status: { Header: , attributes: { - className: 'text-center', - style: { width: '12%' }, + + style: { width: '25%' }, }, Cell: (cellInfo) => { - const { row: { original: content } } = cellInfo; - const { color, title } = getContentStatusDetails(content.status, content.onLine, intl); + const { + row: { original: content }, + } = cellInfo; + const { color/* , title */ } = getContentStatusDetails( + content.status, + content.onLine, + intl, + ); return ( - + ); }, cellAttributes: { @@ -109,9 +109,16 @@ class ContentListCard extends Component { render() { const { - intl, pagination: { page, totalItems, pageSize: perPage }, contentTypes, - onClickAddContent, userPermissions, contents, onSetColumnOrder, + intl, + pagination: { page, pageSize: perPage, totalItems }, + contentTypes, + onClickAddContent, + userPermissions, + contents, + onSetColumnOrder, } = this.props; + + const pagination = { page, perPage, @@ -122,38 +129,46 @@ class ContentListCard extends Component { userPermissions, ) && ( - { - contentTypes.map(contentType => ( - ( - onClickAddContent({ typeCode: contentType.code, typeDescription: contentType.name }) - )} - > - {contentType.name} - - )) - } + {contentTypes.map(contentType => ( + + onClickAddContent({ + typeCode: contentType.code, + typeDescription: contentType.name, + }) + } + > + {contentType.name} + + ))} ); - const messages = Object.keys(paginatorMessages).reduce((acc, curr) => ( - { ...acc, [curr]: intl.formatMessage(paginatorMessages[curr]) } - ), {}); + const messages = Object.keys(paginatorMessages).reduce( + (acc, curr) => ({ + ...acc, + [curr]: intl.formatMessage(paginatorMessages[curr]), + }), + {}, + ); const columns = this.getColumnDefs() || []; return (
-

- +

+
+ + +
{renderAddContentButton}

@@ -163,9 +178,10 @@ class ContentListCard extends Component { columnResizable onColumnReorder={onSetColumnOrder} classNames={{ - table: 'table-striped ContentListCardTable__table', - row: 'VersioningListRow', - cell: 'VersioningListRow__td', + table: 'ContentListCardTable__table table-bordered', + headerGroup: 'table-header', + row: 'table-row', + cell: 'table-cell', }} />
@@ -208,8 +224,8 @@ ContentListCard.defaultProps = { page: 1, totalItems: 0, }, - onSetColumnOrder: () => {}, - columnOrder: ['description', 'lastEditor', 'typeDescription', 'status', 'lastModified'], + onSetColumnOrder: () => { }, + columnOrder: ['description', 'typeDescription', 'status', 'lastModified'], }; export default injectIntl(ContentListCard); diff --git a/src/ui/contents/list-card/ContentListCardContainer.js b/src/ui/contents/list-card/ContentListCardContainer.js index eb0375cb5..9c2df15cc 100644 --- a/src/ui/contents/list-card/ContentListCardContainer.js +++ b/src/ui/contents/list-card/ContentListCardContainer.js @@ -26,6 +26,7 @@ const mapStateToProps = state => ({ }); const mapDispatchToProps = dispatch => ({ + // eslint-disable-next-line no-unused-vars onDidMount: (page = 1, pageSize = 5) => { dispatch(fetchContents({ page, pageSize }, '?sort=lastModified&direction=DESC', namespace)); dispatch(fetchContentTypeListPaged({ page: 1, pageSize: 0 }, '', 'contentTypesTile')); diff --git a/src/ui/contents/status-card/ContentsStatusCard.js b/src/ui/contents/status-card/ContentsStatusCard.js index af08f70db..1771270d1 100644 --- a/src/ui/contents/status-card/ContentsStatusCard.js +++ b/src/ui/contents/status-card/ContentsStatusCard.js @@ -1,9 +1,14 @@ import React, { Component } from 'react'; -import { DonutChart } from 'patternfly-react'; +import { StackedBarChart } from 'patternfly-react'; import { Link } from 'react-router-dom'; import { formatDate, hasAccess } from '@entando/utils'; import PropTypes from 'prop-types'; -import { defineMessages, FormattedMessage, injectIntl, intlShape } from 'react-intl'; +import { + defineMessages, + FormattedMessage, + injectIntl, + intlShape, +} from 'react-intl'; import { SUPERUSER_PERMISSION, @@ -43,11 +48,16 @@ class ContentsStatusCard extends Component { render() { const { - intl, userPermissions, language, contentsStatus, onClickContentList, + intl, + userPermissions, + language, + contentsStatus, + onClickContentList, } = this.props; const { unpublished, ready, published, total, latestModificationDate, - } = contentsStatus; + } = + contentsStatus; const msgs = { contents: intl.formatMessage(contentStatusMsgs.contents), @@ -56,66 +66,205 @@ class ContentsStatusCard extends Component { ready: intl.formatMessage(contentStatusMsgs.ready), }; - const columns = [ - [msgs.published, published], - [msgs.ready, ready], - [msgs.unpublished, unpublished], - ]; - const contentsAvailable = total > 0; const renderBody = !contentsAvailable ? (
- +
) : ( - v, - }, - }} - /> +
+ { + if (a.id === msgs.published || b.id === msgs.published) { + return a - b; + } + return b - a; + }, + groups: [[msgs.published, msgs.ready, msgs.unpublished]], // For stacking + colors: { + [msgs.published]: '#39AC73', + [msgs.ready]: '#FFB219', + [msgs.unpublished]: '#72767B', + }, + }} + axis={{ + rotated: true, // Rotate the chart for horizontal bars + x: { show: false }, // Hide X-axis + y: { show: false }, // Hide Y-axis + }} + grid={{ x: { show: false }, y: { show: false } }} + bar={{ width: 100 }} // Adjust bar thickness + tooltip={{ + format: { + value: v => + `${v} ${intl.formatMessage({ + id: `app.content${v !== 1 ? 's' : ''}`, + defaultMessage: v !== 1 ? 'Content' : 'Contents', + })}`, + }, + }} + legend={{ show: false }} // Hide legend + size={{ height: 20 }} + /> +
+
+
+ + +
+
+ {published}{' '} + +
+
+
+
+ + +
+
+ {ready}{' '} + +
+
+
+
+ + +
+
+ {unpublished}{' '} + +
+
+
+
); return (
- -

- -

- - {(latestModificationDate && contentsAvailable) - ? formatDate(latestModificationDate) : null} - - {renderBody} - { - hasAccess( - [SUPERUSER_PERMISSION, CRUD_CONTENTS_PERMISSION, VALIDATE_CONTENTS_PERMISSION], + +
+
+

+ +

+ + {latestModificationDate && contentsAvailable + ? formatDate(latestModificationDate) + : null} + +
+ {hasAccess( + [ + SUPERUSER_PERMISSION, + CRUD_CONTENTS_PERMISSION, + VALIDATE_CONTENTS_PERMISSION, + ], userPermissions, ) && ( -
- - - -
- ) - } + + + + )} +
+ {renderBody}
); diff --git a/src/ui/dashboard/DashboardPage.js b/src/ui/dashboard/DashboardPage.js index 381b1bd81..45ad7c79f 100644 --- a/src/ui/dashboard/DashboardPage.js +++ b/src/ui/dashboard/DashboardPage.js @@ -13,9 +13,11 @@ import ContentsListCardContainer from 'ui/contents/list-card/ContentListCardCont import AppTourContainer from 'ui/app-tour/AppTourContainer'; import { ADMINISTRATION_AREA_PERMISSION } from 'state/permissions/const'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; export const DashboardPageBody = () => ( + @@ -37,15 +39,14 @@ export const DashboardPageBody = () => ( - + - - - + {ContentsListCardContainer ? : null} + diff --git a/src/ui/dashboard/Languages.js b/src/ui/dashboard/Languages.js index 008d9bdf1..71a5d141d 100644 --- a/src/ui/dashboard/Languages.js +++ b/src/ui/dashboard/Languages.js @@ -5,11 +5,10 @@ import { CardTitle, CardBody, AggregateStatusCount, - Icon, - Button, } from 'patternfly-react'; +import Icon from 'ui/common/icon/Icon'; +import Button from 'ui/common/Button'; import { FormattedMessage } from 'react-intl'; -import { Clearfix } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import { SUPERUSER_PERMISSION } from 'state/permissions/const'; @@ -31,22 +30,23 @@ class Languages extends Component { - - +
+ + +
-
- - {this.props.activeLanguages}  + {this.props.activeLanguages}  diff --git a/src/ui/dashboard/PageStatus.js b/src/ui/dashboard/PageStatus.js index 1a4d70125..f0ef2ba77 100644 --- a/src/ui/dashboard/PageStatus.js +++ b/src/ui/dashboard/PageStatus.js @@ -1,24 +1,16 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { DonutChart } from 'patternfly-react'; +import { StackedBarChart } from 'patternfly-react'; import { hasAccess } from '@entando/utils'; import { Link } from 'react-router-dom'; import { defineMessages, FormattedMessage, injectIntl, intlShape } from 'react-intl'; - import { ROUTE_PAGE_TREE } from 'app-init/router'; import { SUPERUSER_PERMISSION, MANAGE_PAGES_PERMISSION } from 'state/permissions/const'; - import ViewPermissionNoticeOverlay from 'ui/dashboard/ViewPermissionNoticeOverlay'; const pageStatusMsgs = defineMessages({ - pages: { - id: 'app.pages', - defaultMessage: 'Pages', - }, - published: { - id: 'pages.status.published', - defaultMessage: 'Published', - }, + pages: { id: 'app.pages', defaultMessage: 'Pages' }, + published: { id: 'pages.status.published', defaultMessage: 'Published' }, draft: { id: 'pages.status.draft', defaultMessage: 'Published, with pending changes', @@ -47,47 +39,178 @@ class PageStatus extends Component { }, } = this.props; - const msgs = Object.keys(pageStatusMsgs).reduce((acc, curr) => ( - { ...acc, [curr]: intl.formatMessage(pageStatusMsgs[curr]) } - ), {}); + const msgs = Object.keys(pageStatusMsgs).reduce( + (acc, curr) => ({ + ...acc, + [curr]: intl.formatMessage(pageStatusMsgs[curr]), + }), + {}, + ); return (
-

- {lastUpdate} - +
+

+ +

+ {lastUpdate} +
+ {hasAccess( + [SUPERUSER_PERMISSION, MANAGE_PAGES_PERMISSION], + userPermissions, + ) && ( + + + + )} +
+ + (a.id === msgs.published || b.id === msgs.published ? a - b : b - a), + groups: [[msgs.published, msgs.draft, msgs.unpublished]], + colors: { + [msgs.published]: '#39AC73', + [msgs.draft]: '#FFB219', + [msgs.unpublished]: '#72767B', + }, }} - title={{ type: 'total', secondary: msgs.pages }} - legend={{ show: true, position: 'right' }} + axis={{ rotated: true, x: { show: false }, y: { show: false } }} + grid={{ x: { show: false }, y: { show: false } }} + bar={{ width: 100 }} tooltip={{ + tooltip: { show: true }, format: { - value: v => v, + value: v => + `${v} ${intl.formatMessage({ + id: `app.page${v !== 1 ? 's' : ''}`, + defaultMessage: v !== 1 ? 'Pages' : 'Page', + })}`, }, }} + legend={{ show: false }} + size={{ height: 20 }} /> - { - hasAccess([SUPERUSER_PERMISSION, MANAGE_PAGES_PERMISSION], userPermissions) && ( -
- - - +
+
+
+ + +
+
+ {published}{' '} + +
+
+
+
+ +
- ) - } +
+ {draft}{' '} + +
+
+
+
+ + +
+
+ {unpublished}{' '} + +
+
+
); @@ -107,8 +230,6 @@ PageStatus.propTypes = { }).isRequired, }; -PageStatus.defaultProps = { - userPermissions: [], -}; +PageStatus.defaultProps = { userPermissions: [] }; export default injectIntl(PageStatus); diff --git a/src/ui/dashboard/PagesList.js b/src/ui/dashboard/PagesList.js index 70e588264..e891d0eef 100644 --- a/src/ui/dashboard/PagesList.js +++ b/src/ui/dashboard/PagesList.js @@ -1,19 +1,18 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { Button, Paginator } from 'patternfly-react'; -import { Clearfix } from 'react-bootstrap'; +import { Paginator } from 'patternfly-react'; import { Link } from 'react-router-dom'; import { FormattedMessage, injectIntl, intlShape } from 'react-intl'; import EllipsisWithTooltip from 'react-ellipsis-with-tooltip'; import { DataTable } from '@entando/datatable'; - -import PageStatusIcon from 'ui/pages/common/PageStatusIcon'; import { ROUTE_PAGE_ADD } from 'app-init/router'; import { formatDate, hasAccess } from '@entando/utils'; import paginatorMessages from 'ui/paginatorMessages'; import { MANAGE_PAGES_PERMISSION } from 'state/permissions/const'; - import ViewPermissionNoticeOverlay from 'ui/dashboard/ViewPermissionNoticeOverlay'; +import Icon from 'ui/common/icon/Icon'; +import Button from 'ui/common/Button'; +import StatusBadge from 'ui/pages/common/StatusBadge'; class PagesList extends Component { constructor(props) { @@ -25,13 +24,11 @@ class PagesList extends Component { componentDidMount() { const { - onWillMount, - columnOrder, - onSetColumnOrder, - userPermissions, - } = this.props; + onWillMount, columnOrder, onSetColumnOrder, userPermissions, + } = + this.props; if (!columnOrder.length) { - onSetColumnOrder(['fullTitles', 'pageModel', 'numWidget', 'status', 'lastModified']); + onSetColumnOrder(['pageModel', 'numWidget', 'status', 'lastModified']); } if (hasAccess(MANAGE_PAGES_PERMISSION, userPermissions)) { onWillMount(); @@ -39,30 +36,18 @@ class PagesList extends Component { } getColumnDefs() { - const { columnOrder, language } = this.props; + const { columnOrder } = this.props; const columnDefs = { - fullTitles: { - Header: , - attributes: { - style: { width: '32%' }, - }, - Cell: (cellInfo) => { - const { row: { original: page } } = cellInfo; - return ( - - {page.fullTitles[language]} - - ); - }, - }, pageModel: { Header: , attributes: { - style: { width: '20%' }, + style: { width: '25%' }, }, Cell: (cellInfo) => { - const { row: { original: page } } = cellInfo; + const { + row: { original: page }, + } = cellInfo; return ( {page.pageModel} @@ -72,19 +57,21 @@ class PagesList extends Component { }, numWidget: { Header: , - Cell: ({ value }) => `${value} widget(s)`, + Cell: ({ value }) => `${value} widget${value > 1 ? 's' : ''}`, + attributes: { + style: { width: '25%' }, + }, }, status: { Header: , attributes: { - className: 'text-center', - style: { width: '10%' }, + style: { width: '25%' }, }, Cell: (cellInfo) => { - const { row: { original: page } } = cellInfo; - return ( - - ); + const { + row: { original: page }, + } = cellInfo; + return ; }, cellAttributes: { className: 'text-center', @@ -93,7 +80,7 @@ class PagesList extends Component { lastModified: { Header: , attributes: { - style: { width: '19%' }, + style: { width: '25%' }, }, Cell: ({ value }) => formatDate(value), }, @@ -116,36 +103,36 @@ class PagesList extends Component { render() { const { - pages, - onSetColumnOrder, - page, - pageSize: perPage, + pages, onSetColumnOrder, page, pageSize: perPage, } = this.props; - const pagination = { - page, - perPage, - perPageOptions: [5, 10, 15], - }; - + const pagination = { page, perPage, perPageOptions: [5, 10, 15] }; const { intl } = this.props; - const messages = Object.keys(paginatorMessages).reduce((acc, curr) => ( - { ...acc, [curr]: intl.formatMessage(paginatorMessages[curr]) } - ), {}); + const messages = Object.keys(paginatorMessages).reduce( + (acc, curr) => ({ + ...acc, + [curr]: intl.formatMessage(paginatorMessages[curr]), + }), + {}, + ); const columns = this.getColumnDefs() || []; return (
-

- +

+
+ + +

@@ -156,8 +143,10 @@ class PagesList extends Component { columnResizable onColumnReorder={onSetColumnOrder} classNames={{ - table: 'PageTemplateListTable__table table-striped', - cell: 'FragmentListRow__td', + table: 'PageTemplateListTable__table table-bordered', + headerGroup: 'table-header', + row: 'table-row', + cell: 'table-cell', }} />

@@ -169,7 +158,6 @@ class PagesList extends Component { onPerPageSelect={this.changePageSize} messages={messages} /> -

); @@ -182,10 +170,6 @@ PagesList.propTypes = { userPermissions: PropTypes.arrayOf(PropTypes.string), pages: PropTypes.arrayOf(PropTypes.shape({ code: PropTypes.string, - fullTitles: PropTypes.shape({ - en: PropTypes.string, - it: PropTypes.string, - }), status: PropTypes.string, numWidget: PropTypes.number, lastModified: PropTypes.string, @@ -193,7 +177,6 @@ PagesList.propTypes = { page: PropTypes.number.isRequired, pageSize: PropTypes.number.isRequired, totalItems: PropTypes.number.isRequired, - language: PropTypes.string.isRequired, columnOrder: PropTypes.arrayOf(PropTypes.string), onSetColumnOrder: PropTypes.func, }; @@ -201,8 +184,8 @@ PagesList.propTypes = { PagesList.defaultProps = { pages: [], userPermissions: [], - columnOrder: ['fullTitles', 'pageModel', 'numWidget', 'status', 'lastModified'], - onSetColumnOrder: () => {}, + columnOrder: ['pageModel', 'numWidget', 'status', 'lastModified'], + onSetColumnOrder: () => { }, }; export default injectIntl(PagesList); diff --git a/src/ui/dashboard/UserManagement.js b/src/ui/dashboard/UserManagement.js index b994ae827..20c9fe137 100644 --- a/src/ui/dashboard/UserManagement.js +++ b/src/ui/dashboard/UserManagement.js @@ -5,11 +5,10 @@ import { CardTitle, CardBody, AggregateStatusCount, - Icon, - Button, } from 'patternfly-react'; +import Icon from 'ui/common/icon/Icon'; +import Button from 'ui/common/Button'; import { PermissionCheck, hasAccess } from '@entando/utils'; -import { Clearfix } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import { FormattedMessage } from 'react-intl'; import { @@ -48,42 +47,45 @@ class UserManagement extends Component { - - +
+ + +
-
- - - - {users}  - - - - + +
+ + + {users}  + + + + +
{isSuperuser && ( - +
- {groups}  + {groups}  - - )} +
)}
diff --git a/src/ui/dashboard/UserManagementContainer.js b/src/ui/dashboard/UserManagementContainer.js index ef44f6901..e28263f0d 100644 --- a/src/ui/dashboard/UserManagementContainer.js +++ b/src/ui/dashboard/UserManagementContainer.js @@ -12,6 +12,7 @@ export const mapStateToProps = state => ({ groups: getGroupsTotal(state), }); + export const mapDispatchToProps = (dispatch, props) => ({ onDidMount: () => { dispatch(fetchUsersTotal()); diff --git a/src/ui/dashboard/UxPatterns.js b/src/ui/dashboard/UxPatterns.js index 7f11d03ef..ca3e1ab6f 100644 --- a/src/ui/dashboard/UxPatterns.js +++ b/src/ui/dashboard/UxPatterns.js @@ -5,11 +5,10 @@ import { CardTitle, CardBody, AggregateStatusCount, - Icon, - Button, } from 'patternfly-react'; +import Icon from 'ui/common/icon/Icon'; +import Button from 'ui/common/Button'; import { hasAccess } from '@entando/utils'; -import { Clearfix } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import { FormattedMessage } from 'react-intl'; @@ -34,35 +33,46 @@ class UxPatterns extends Component { - - +
+ + +
{isSuperuser && ( )} -
- - - {this.props.widgets}  - - - - - - - {this.props.pageTemplates}  - - - - +
+ + + {this.props.widgets}  + + + + +
+
+ + + {this.props.pageTemplates}  + + + + +
diff --git a/src/ui/data-types/add/AddDataTypesPage.js b/src/ui/data-types/add/AddDataTypesPage.js index 94108b18d..e63cca12c 100644 --- a/src/ui/data-types/add/AddDataTypesPage.js +++ b/src/ui/data-types/add/AddDataTypesPage.js @@ -1,10 +1,9 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; +import { Grid, Row, Col } from 'patternfly-react'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import AddFormContainer from 'ui/data-types/add/AddFormContainer'; import { ROUTE_DATA_TYPE_LIST } from 'app-init/router'; import withPermissions from 'ui/auth/withPermissions'; @@ -12,22 +11,13 @@ import { SUPERUSER_PERMISSION } from 'state/permissions/const'; const AddDataTypesPage = () => ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - + - - - - - - - - - - - - + ( - + {database.code} @@ -63,12 +63,12 @@ class DatabaseListTable extends Component { return ( - + - - - - + + + diff --git a/src/ui/database/list/ListDatabasePage.js b/src/ui/database/list/ListDatabasePage.js index 06be35199..c272be70b 100644 --- a/src/ui/database/list/ListDatabasePage.js +++ b/src/ui/database/list/ListDatabasePage.js @@ -1,31 +1,23 @@ import React from 'react'; -import { Grid, Row, Col, Button, Breadcrumb } from 'patternfly-react'; +import { Grid, Row, Col, Button } from 'patternfly-react'; import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; import DatabaseListTableContainer from 'ui/database/list/DatabaseListTableContainer'; import withPermissions from 'ui/auth/withPermissions'; import { SUPERUSER_PERMISSION } from 'state/permissions/const'; import { ROUTE_DATABASE_ADD } from 'app-init/router'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; export const DatabaseListPageBody = () => ( + - - - - - - - - - - - - + { const { pathname } = useLocation(); const history = useHistory(); - const breadcrumb = ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ( - - - - )} - /> - - - - - ); + const getBreadbrumbs = useCallback(() => { + const rootBreadcrumb = [{ label: 'menu.settings' }, { label: 'menu.emailConfig' }]; + + switch (pathname) { + case ROUTE_EMAIL_CONFIG: + return [...rootBreadcrumb, { label: 'emailConfig.smtpServer' }]; + case ROUTE_EMAIL_CONFIG_SENDERS: + return [...rootBreadcrumb, { label: 'emailConfig.senderMgmt' }]; + case ROUTE_EMAIL_CONFIG_SENDERS_ADD: + return [...rootBreadcrumb, { label: 'emailConfig.senderMgmt', to: ROUTE_EMAIL_CONFIG_SENDERS }, { label: 'emailConfig.senderMgmt.new' }]; + default: + + if (pathname.includes('/email-config/senders/edit/')) { + const param = pathname.split('/').pop(); + return [ + ...rootBreadcrumb, + { label: 'emailConfig.senderMgmt', to: ROUTE_EMAIL_CONFIG_SENDERS }, + { children: }, + ]; + } + } + return rootBreadcrumb; + }, [pathname]); const tabs = ( -
    - +
+ + ); return ( + - {breadcrumb} { component={EditEmailSenderFormContainer} /> - -
+
+
- -
{tabs} - - + + + + { - + diff --git a/src/ui/email-config/EmailConfigSmtpServer.js b/src/ui/email-config/EmailConfigSmtpServer.js index e7d068c90..5f951cd46 100644 --- a/src/ui/email-config/EmailConfigSmtpServer.js +++ b/src/ui/email-config/EmailConfigSmtpServer.js @@ -123,7 +123,12 @@ const EmailConfigSmtpServerBody = ({ ); return ( - + diff --git a/src/ui/file-browser/add/CreateFolderPage.js b/src/ui/file-browser/add/CreateFolderPage.js index 5e824032d..5bc6055af 100644 --- a/src/ui/file-browser/add/CreateFolderPage.js +++ b/src/ui/file-browser/add/CreateFolderPage.js @@ -1,8 +1,6 @@ import React from 'react'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; -import { FormattedMessage } from 'react-intl'; +import { Grid, Row, Col } from 'patternfly-react'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; import FileBreadcrumbContainer from 'ui/file-browser/common/FileBreadcrumbContainer'; @@ -10,25 +8,17 @@ import FileButtonsGroupContainer from 'ui/file-browser/common/FileButtonsGroupCo import CreateFolderFormContainer from 'ui/file-browser/add/CreateFolderFormContainer'; import withPermissions from 'ui/auth/withPermissions'; import { SUPERUSER_PERMISSION } from 'state/permissions/const'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; export const CreateFolderPageBody = () => ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - + diff --git a/src/ui/file-browser/list/ListFilesPage.js b/src/ui/file-browser/list/ListFilesPage.js index ae420fcb1..c8f786881 100644 --- a/src/ui/file-browser/list/ListFilesPage.js +++ b/src/ui/file-browser/list/ListFilesPage.js @@ -1,10 +1,8 @@ import React from 'react'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; -import { FormattedMessage } from 'react-intl'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; +import { Grid, Row, Col } from 'patternfly-react'; import InternalPage from 'ui/internal-page/InternalPage'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import PageTitle from 'ui/internal-page/PageTitle'; import FilesListTableContainer from 'ui/file-browser/list/FilesListTableContainer'; import FileBreadcrumbContainer from 'ui/file-browser/common/FileBreadcrumbContainer'; @@ -14,19 +12,12 @@ import { SUPERUSER_PERMISSION } from 'state/permissions/const'; export const ListFilesPageBody = () => ( + - - - - - - - - - - - - ( - + diff --git a/src/ui/file-browser/upload/UploadFileBrowserPage.js b/src/ui/file-browser/upload/UploadFileBrowserPage.js index 813a14038..013d7cf45 100644 --- a/src/ui/file-browser/upload/UploadFileBrowserPage.js +++ b/src/ui/file-browser/upload/UploadFileBrowserPage.js @@ -1,12 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Grid, Row, Col, Button, Breadcrumb, Icon, ButtonGroup } from 'patternfly-react'; +import { Grid, Row, Col, Button, Icon, ButtonGroup } from 'patternfly-react'; import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; - import InternalPage from 'ui/internal-page/InternalPage'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import PageTitle from 'ui/internal-page/PageTitle'; import UploadFileBrowserFormContainer from 'ui/file-browser/upload/UploadFileBrowserFormContainer'; import FileBreadcrumbContainer from 'ui/file-browser/common/FileBreadcrumbContainer'; @@ -30,19 +29,12 @@ export const UploadFileBrowserPageBody = ({ location: { pathname } }) => { ); return ( + - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - diff --git a/src/ui/fragments/detail/DetailFragmentPage.js b/src/ui/fragments/detail/DetailFragmentPage.js index 5891f72f4..73e583fac 100644 --- a/src/ui/fragments/detail/DetailFragmentPage.js +++ b/src/ui/fragments/detail/DetailFragmentPage.js @@ -1,14 +1,14 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -import { Grid, Breadcrumb, Row, Col } from 'patternfly-react'; +import { Grid, Row, Col } from 'patternfly-react'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import PageTitle from 'ui/internal-page/PageTitle'; import InternalPage from 'ui/internal-page/InternalPage'; import DetailFragmentTable from 'ui/fragments/detail/DetailFragmentTable'; import FragmentReferenceTable from 'ui/fragments/detail/FragmentReferenceTable'; import PageTemplateReferenceTable from 'ui/fragments/detail/PageTemplateReferenceTable'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import WidgetTypeReferenceTable from 'ui/fragments/detail/WidgetTypeReferenceTable'; import { ROUTE_FRAGMENT_LIST } from 'app-init/router'; @@ -19,72 +19,61 @@ class DetailFragmentPage extends Component { render() { return ( + - - - - - - - - - - - - - - - - - + + -
-
- -

- -

-
- - - -
- -

- -

-
- - - -
- -

- -

-
- - - - - + + +

+ +

+
+ + + +
+ +

+ +

+
+ + + +
+ +

+ +

+
+ + + + ); diff --git a/src/ui/fragments/edit/EditFragmentPage.js b/src/ui/fragments/edit/EditFragmentPage.js index 8a67741d3..f299b19de 100644 --- a/src/ui/fragments/edit/EditFragmentPage.js +++ b/src/ui/fragments/edit/EditFragmentPage.js @@ -1,13 +1,12 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; -import { Breadcrumb, Grid } from 'patternfly-react'; +import { Grid } from 'patternfly-react'; import { Row, Col } from 'react-bootstrap'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import EditFormContainer from 'ui/fragments/edit/EditFormContainer'; import PageTitle from 'ui/internal-page/PageTitle'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import { ROUTE_FRAGMENT_LIST } from 'app-init/router'; const FRAGMENT_HELP = 'fragment.help'; @@ -25,22 +24,13 @@ class EditFragmentPage extends Component { render() { return ( + - - - - - - - - - - - - - - - diff --git a/src/ui/fragments/list/FragmentGrid.js b/src/ui/fragments/list/FragmentGrid.js new file mode 100644 index 000000000..71f37e829 --- /dev/null +++ b/src/ui/fragments/list/FragmentGrid.js @@ -0,0 +1,139 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { intlShape, injectIntl } from 'react-intl'; +import { PaginationRow, Spinner } from 'patternfly-react'; +import FragmentListMenuActions from 'ui/fragments/list/FragmentListMenuActions'; +import DeleteFragmentModalContainer from 'ui/fragments/list/DeleteFragmentModalContainer'; +import paginatorMessages from 'ui/paginatorMessages'; +import CardList from 'ui/common/CardList'; + +class FragmentGrid extends Component { + constructor(props) { + super(props); + + this.state = { + pageInputValue: props.page, + }; + + this.changePage = this.changePage.bind(this); + this.changePageSize = this.changePageSize.bind(this); + this.handleFormSubmit = this.handleFormSubmit.bind(this); + this.handlePageInput = this.handlePageInput.bind(this); + } + + componentWillMount() { + const { onWillMount } = this.props; + onWillMount(); + } + + changePage(page) { + const { filters } = this.props; + this.props.onWillMount({ page, pageSize: this.props.pageSize }, filters); + + this.setState({ pageInputValue: page }); + } + + changePageSize(pageSize) { + const { filters } = this.props; + this.props.onWillMount({ page: 1, pageSize }, filters); + } + + handleFormSubmit() { + this.changePage(this.state.pageInputValue); + } + + handlePageInput(e) { + this.setState({ pageInputValue: e.target.value }); + } + + renderContent() { + const { + page, + pageSize, + intl, + fragments, + totalItems, + lastPage, + } = this.props; + const pagination = { + page, + perPage: pageSize, + perPageOptions: [20, 40, 100], + }; + + + const messages = Object.keys(paginatorMessages).reduce((acc, curr) => ( + { ...acc, [curr]: intl.formatMessage(paginatorMessages[curr]) } + ), {}); + + const itemsStart = totalItems === 0 ? 0 : ((page - 1) * pageSize) + 1; + const itemsEnd = Math.min(page * pageSize, totalItems); + + const renderFragmentListMenuActions = props => ( + + ); + + return ( +
+ + this.changePage(1)} + onPreviousPage={() => this.changePage(page - 1)} + onNextPage={() => this.changePage(page + 1)} + onLastPage={() => this.changePage(lastPage)} + messages={messages} + /> +
+ ); + } + + render() { + return ( +
+ + {this.renderContent()} + + +
+ ); + } +} + +FragmentGrid.propTypes = { + intl: intlShape.isRequired, + onWillMount: PropTypes.func, + loading: PropTypes.bool, + fragments: PropTypes.arrayOf(PropTypes.shape({ + code: PropTypes.string.isRequired, + isLocked: PropTypes.bool, + widgetType: PropTypes.shape({ + code: PropTypes.string, + title: PropTypes.string, + }).isRequired, + pluginCode: PropTypes.string, + })), + page: PropTypes.number.isRequired, + pageSize: PropTypes.number.isRequired, + totalItems: PropTypes.number.isRequired, + lastPage: PropTypes.number.isRequired, + filters: PropTypes.string, +}; + +FragmentGrid.defaultProps = { + onWillMount: () => { }, + loading: false, + fragments: [], + filters: '', +}; + +export default injectIntl(FragmentGrid); diff --git a/src/ui/fragments/list/FragmentGridContainer .js b/src/ui/fragments/list/FragmentGridContainer .js new file mode 100644 index 000000000..4e3555051 --- /dev/null +++ b/src/ui/fragments/list/FragmentGridContainer .js @@ -0,0 +1,50 @@ +import { connect } from 'react-redux'; + +import { fetchFragments } from 'state/fragments/actions'; +import { getFragmentList, getFilters } from 'state/fragments/selectors'; +import { getLoading } from 'state/loading/selectors'; +import { getCurrentPage, getTotalItems, getPageSize, getLastPage } from 'state/pagination/selectors'; +import { setVisibleModal, setInfo } from 'state/modal/actions'; + +import FragmentGrid from 'ui/fragments/list/FragmentGrid'; +import { MODAL_ID } from 'ui/fragments/list/DeleteFragmentModal'; + +export const mapStateToProps = state => ( + { + fragments: getFragmentList(state).map((f => ( + { + title: f.code, + subtitle: Object.is(f.widgetType, null) ? '' : f.widgetType.title, + description: f.pluginCode || '', + ...f, + }))), + page: getCurrentPage(state), + totalItems: getTotalItems(state), + pageSize: getPageSize(state), + lastPage: getLastPage(state), + loading: getLoading(state).fragments, + filters: getFilters(state), + } +); + +export const mapDispatchToProps = dispatch => ({ + onWillMount: (page = { page: 1, pageSize: 20 }, params) => { + dispatch(fetchFragments(page, params)); + }, + onClickDelete: (fragment) => { + dispatch(setVisibleModal(MODAL_ID)); + dispatch(setInfo({ type: 'fragment', code: fragment.code })); + }, +}); + +const FragmentGridContainer = + connect( + mapStateToProps, + mapDispatchToProps, + null, + { + pure: false, + }, + )(FragmentGrid); + +export default FragmentGridContainer; diff --git a/src/ui/fragments/list/FragmentListContent.js b/src/ui/fragments/list/FragmentListContent.js index 567df1183..33eede0b1 100644 --- a/src/ui/fragments/list/FragmentListContent.js +++ b/src/ui/fragments/list/FragmentListContent.js @@ -1,38 +1,26 @@ import React from 'react'; -import { Row, Col, Button } from 'patternfly-react'; -import { FormattedMessage } from 'react-intl'; -import { Link } from 'react-router-dom'; - -import FragmentListTableContainer from 'ui/fragments/list/FragmentListTableContainer'; -import FragmentSearchFormContainer from 'ui/fragments/list/FragmentSearchFormContainer'; -import { ROUTE_FRAGMENT_ADD } from 'app-init/router'; +// import { Row, Col , Button } from 'patternfly-react'; +// import { FormattedMessage } from 'react-intl'; +// import { Link } from 'react-router-dom'; +// import { ROUTE_FRAGMENT_ADD } from 'app-init/router'; +// import FragmentListTableContainer from 'ui/fragments/list/FragmentListTableContainer'; +import FragmentGridContainer from 'ui/fragments/list/FragmentGridContainer '; const FragmentListContent = () => (
- -
- - - - - - -
- -
- - - - - + + {/* */} + {/* + + */} ); diff --git a/src/ui/fragments/list/FragmentListMenuActions.js b/src/ui/fragments/list/FragmentListMenuActions.js index f222d3f35..0baece41b 100644 --- a/src/ui/fragments/list/FragmentListMenuActions.js +++ b/src/ui/fragments/list/FragmentListMenuActions.js @@ -10,6 +10,7 @@ import { ROUTE_FRAGMENT_CLONE, ROUTE_FRAGMENT_DETAIL, } from 'app-init/router'; +import Icon from 'ui/common/icon/Icon'; class FragmentListMenuActions extends Component { constructor(props) { @@ -37,30 +38,42 @@ class FragmentListMenuActions extends Component { ); return ( - - - - - - +
+ + +
+
+ + +
+
+ + +
+
+ + + + +
); } diff --git a/src/ui/fragments/list/FragmentListTable.js b/src/ui/fragments/list/FragmentListTable.js index acab6c00d..6776150d3 100644 --- a/src/ui/fragments/list/FragmentListTable.js +++ b/src/ui/fragments/list/FragmentListTable.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { Col, Spinner, PaginationRow } from 'patternfly-react'; +import { /* Col, */Spinner, PaginationRow } from 'patternfly-react'; import { FormattedMessage, intlShape, injectIntl } from 'react-intl'; import { DataTable } from '@entando/datatable'; @@ -122,7 +122,7 @@ class FragmentListTable extends Component { }; return ( -
+ this.changePage(lastPage)} messages={messages} /> - ); + ); } render() { @@ -189,11 +189,11 @@ FragmentListTable.propTypes = { }; FragmentListTable.defaultProps = { - onWillMount: () => {}, + onWillMount: () => { }, loading: false, fragments: [], filters: '', - onSetColumnOrder: () => {}, + onSetColumnOrder: () => { }, columnOrder: [], }; diff --git a/src/ui/fragments/list/FragmentSearchForm.js b/src/ui/fragments/list/FragmentSearchForm.js index 4a39da9e5..88a48b740 100644 --- a/src/ui/fragments/list/FragmentSearchForm.js +++ b/src/ui/fragments/list/FragmentSearchForm.js @@ -1,8 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { reduxForm, Field } from 'redux-form'; -import { FormattedMessage, defineMessages, injectIntl, intlShape } from 'react-intl'; -import { Row, Col, FormGroup, Button } from 'patternfly-react'; +import { defineMessages, injectIntl, intlShape } from 'react-intl'; const msgs = defineMessages({ codePlaceholder: { @@ -17,6 +16,14 @@ const msgs = defineMessages({ id: 'fragment.form.edit.plugin', defaultMessage: 'Edit Plugin', }, + widgetPlaceholder: { + id: 'fragment.form.edit.widgetType"', + defaultMessage: 'Widget type', + }, + pluginPlaceholder: { + id: 'fragment.form.edit.plugin', + defaultMessage: 'Plugin', + }, }); const widgetCategoryMsgs = defineMessages({ @@ -82,75 +89,40 @@ export class FragmentSearchFormBody extends Component { render() { const { intl, widgetTypes, plugins } = this.props; return ( - -

- - - - - - - - - - - - - - - {renderSelectOptgroup(widgetTypes, intl)} - - - - - - - - - - - {plugins.map(plugin => - )} - - - - - - - - - - - + + + + + + )} + ); } @@ -165,7 +137,7 @@ FragmentSearchFormBody.propTypes = { }; FragmentSearchFormBody.defaultProps = { - onWillMount: () => {}, + onWillMount: () => { }, widgetTypes: [], plugins: [], }; diff --git a/src/ui/fragments/list/ListFragmentPage.js b/src/ui/fragments/list/ListFragmentPage.js index b03b4e1ad..6f4c57f74 100644 --- a/src/ui/fragments/list/ListFragmentPage.js +++ b/src/ui/fragments/list/ListFragmentPage.js @@ -1,34 +1,40 @@ import React, { Component } from 'react'; -import { Grid, Row, Col, Breadcrumb, MenuItem } from 'patternfly-react'; +import { Grid, Row, Col } from 'patternfly-react'; import { FormattedMessage } from 'react-intl'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; +import { ButtonToolbar } from 'react-bootstrap'; +import cx from 'classnames'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; import SettingsFragmentFormContainer from 'ui/fragments/list/SettingsFragmentFormContainer'; +import FragmentSearchFormContainer from 'ui/fragments/list/FragmentSearchFormContainer'; import FragmentListContent from 'ui/fragments/list/FragmentListContent'; import withPermissions from 'ui/auth/withPermissions'; +import Button from 'ui/common/Button'; +import Icon from 'ui/common/icon/Icon'; import { SUPERUSER_PERMISSION } from 'state/permissions/const'; +import { Link } from 'react-router-dom'; +import { ROUTE_FRAGMENT_ADD } from 'app-init/router'; -const TAB_LIST = 'list'; -const TAB_SETTINGS = 'settings'; +const VIEW_LIST = 'list'; +const VIEW_SETTINGS = 'settings'; export class ListFragmentPageBody extends Component { constructor(props) { super(props); - this.setActiveTab = this.setActiveTab.bind(this); + this.setActiveView = this.setActiveView.bind(this); this.state = { - activeTab: TAB_LIST, + activeView: VIEW_LIST, }; } - setActiveTab(activeTab) { - this.setState({ activeTab }); + setActiveView(activeView) { + this.setState({ activeView }); } renderContent() { - return this.state.activeTab === TAB_LIST + return this.state.activeView === VIEW_LIST ? : ; } @@ -36,46 +42,58 @@ export class ListFragmentPageBody extends Component { render() { return ( + - - - - - - - - - - - - + > +
+ +
+
- -
    - this.setActiveTab(TAB_LIST)} + + +
    +
    + this.setActiveView(VIEW_LIST)} > + - - this.setActiveTab(TAB_SETTINGS)} + + this.setActiveView(VIEW_SETTINGS)} > + - -
- + + + + + + + + + {this.renderContent()} - {this.renderContent()} ); diff --git a/src/ui/fragments/list/SettingsFragmentForm.js b/src/ui/fragments/list/SettingsFragmentForm.js index 575c27fca..03bfa3967 100644 --- a/src/ui/fragments/list/SettingsFragmentForm.js +++ b/src/ui/fragments/list/SettingsFragmentForm.js @@ -13,43 +13,39 @@ export class SettingsFragmentFormBody extends React.Component { render() { return (
-
- -
-
- - -
- - - - - - - - - - -
- - -
- - - - - - - + +
+ + +
+ + + + + + + + + + +
+ + +
+ + + + + diff --git a/src/ui/groups/add/AddGroupPage.js b/src/ui/groups/add/AddGroupPage.js index b5b02c5c4..db87fdb76 100644 --- a/src/ui/groups/add/AddGroupPage.js +++ b/src/ui/groups/add/AddGroupPage.js @@ -1,10 +1,8 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; +import { Grid, Row, Col } from 'patternfly-react'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import AddFormContainer from 'ui/groups/add/AddFormContainer'; import { ROUTE_GROUP_LIST } from 'app-init/router'; import withPermissions from 'ui/auth/withPermissions'; @@ -13,22 +11,13 @@ import { SUPERUSER_PERMISSION } from 'state/permissions/const'; export const AddGroupPageBody = () => ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - 0) { - const pagination = { - page, - perPage: pageSize, - perPageOptions: [5, 10, 15, 25, 50], - }; + const pagination = { page, perPage: pageSize, perPageOptions: [5, 10, 15, 25, 50] }; + + const columns = [ + { title: 'app.name', field: 'name', className: 'GroupListTable__th-lg' }, + { title: 'app.code', field: 'code', className: 'GroupListTable__th-lg' }, + { + title: '', + field: 'actions', + className: 'GroupListTable__th-xs text-center', + render: props => ( +
+ +
+ ), + }, + ]; - const messages = Object.keys(paginatorMessages).reduce((acc, curr) => ( - { ...acc, [curr]: intl.formatMessage(paginatorMessages[curr]) } - ), {}); return ( -
-
+
{file.size !== null ? `${file.size} byte` : null} {file.lastModifiedTime} + {renderUpLink()}
- - - - - - - - - {this.renderTableRows()} - -
- -
- - + ); } return ( @@ -122,10 +118,10 @@ GroupListTable.propTypes = { }; GroupListTable.defaultProps = { - onWillMount: () => {}, + onWillMount: () => { }, loading: false, groups: [], - onClickDelete: () => {}, + onClickDelete: () => { }, }; export default injectIntl(GroupListTable); diff --git a/src/ui/groups/list/ListGroupPage.js b/src/ui/groups/list/ListGroupPage.js index 4db24ba4d..427fc22fc 100644 --- a/src/ui/groups/list/ListGroupPage.js +++ b/src/ui/groups/list/ListGroupPage.js @@ -1,11 +1,10 @@ import React from 'react'; -import { Grid, Row, Col, Button, Breadcrumb } from 'patternfly-react'; +import { Grid, Row, Col, Button } from 'patternfly-react'; import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import GroupListTableContainer from 'ui/groups/list/GroupListTableContainer'; import ErrorsAlertContainer from 'ui/common/form/ErrorsAlertContainer'; import { ROUTE_GROUP_ADD } from 'app-init/router'; @@ -14,19 +13,12 @@ import { SUPERUSER_PERMISSION } from 'state/permissions/const'; export const ListGroupPageBody = () => ( + - - - - - - - - - - - - { + const [container, setContainer] = useState(document.getElementById('header-breadcrumbs')); + + useEffect(() => { + if (!container) { + const fallbackContainer = document.getElementById('header-breadcrumbs'); + setContainer(fallbackContainer); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + if (!container) return
; + + return createPortal( + + + + App Builder + + {breadcrumbs.map(({ + label, customLabel = '', children, ...rest +}) => ( + + {label && } + {customLabel && { customLabel }} + {children && children} + ))} + , + container, + ); +}; + +HeaderBreadcrumb.propTypes = { + breadcrumbs: PropTypes.arrayOf(PropTypes.shape({ + label: PropTypes.string, + to: PropTypes.string, + active: PropTypes.boolean, + customLabel: PropTypes.string, + children: PropTypes.node, + })).isRequired, +}; + +export default HeaderBreadcrumb; diff --git a/src/ui/internal-page/PageTitle.js b/src/ui/internal-page/PageTitle.js index 3566eced3..ef24e1eea 100644 --- a/src/ui/internal-page/PageTitle.js +++ b/src/ui/internal-page/PageTitle.js @@ -1,9 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; +import cx from 'classnames'; import { FormattedMessage } from 'react-intl'; import { OverlayTrigger, Popover } from 'patternfly-react'; import { Link } from 'react-router-dom'; - +import { colorContent05 } from 'variables.scss'; +import Icon from 'ui/common/icon/Icon'; const helpIcon = helpId => ( helpId ? @@ -20,7 +22,7 @@ const helpIcon = helpId => ( trigger={['click']} rootClose > - + : null @@ -43,16 +45,21 @@ const PageTitle = ({ configLink, hideConfigLink, 'data-testid': dataTestId, + children, + className, }) => ( -
+

- - {!hideConfigLink && configIcon(configLink)} +
+ + {!hideConfigLink && configIcon(configLink)} + {children} +
{helpIcon(helpId)}

-
+
); PageTitle.propTypes = { @@ -62,6 +69,8 @@ PageTitle.propTypes = { hideConfigLink: PropTypes.bool, titleParam: PropTypes.shape({}), 'data-testid': PropTypes.string, + children: PropTypes.node, + className: PropTypes.string, }; PageTitle.defaultProps = { @@ -70,6 +79,8 @@ PageTitle.defaultProps = { hideConfigLink: false, titleParam: {}, 'data-testid': '', + children: null, + className: '', }; export default PageTitle; diff --git a/src/ui/internal-page/VerticalMenuContainer.js b/src/ui/internal-page/VerticalMenuContainer.js index 311cb5cc1..5927af9b0 100644 --- a/src/ui/internal-page/VerticalMenuContainer.js +++ b/src/ui/internal-page/VerticalMenuContainer.js @@ -79,8 +79,8 @@ const renderCmsMenuItems = (intl, userPermissions, systemReport, currSysConfigAd {}} - iconClass="fa fa-file-text-o" + onClick={() => { }} + iconClass="VerticalMenuContainer_Icon Contents" title={intl.formatMessage({ id: 'menu.cms' })} > { @@ -182,16 +182,19 @@ const getHeader = onStartTutorial => ( - - - - - - +
+
+ + + + + + +
); const EntandoMenu = ({ @@ -222,7 +225,7 @@ const EntandoMenu = ({ }; return ( -
+
history.push(ROUTE_DASHBOARD)} - iconClass="fa fa-window-maximize" + iconClass="VerticalMenuContainer_Icon Dashboard" title={intl.formatMessage({ id: 'menu.dashboard', defaultMessage: 'Dashboard' })} /> { @@ -256,7 +259,7 @@ const EntandoMenu = ({ id="menu-page-creator" className="app-tour-step-3" onClick={() => onNextStep(4)} - iconClass="fa fa-files-o" + iconClass="VerticalMenuContainer_Icon Pages" title={intl.formatMessage({ id: 'menu.pageDesigner', defaultMessage: 'Pages' })} > {}} - iconClass="fa fa-object-ungroup" + onClick={() => { }} + iconClass="VerticalMenuContainer_Icon Components" title={intl.formatMessage({ id: 'menu.uxComponents', defaultMessage: 'Components' })} > {}} - iconClass="fa fa-users" + onClick={() => { }} + iconClass="VerticalMenuContainer_Icon Users" title={intl.formatMessage({ id: 'menu.userSettings', defaultMessage: 'Users' })} > {}} + onClick={() => { }} iconClass="fa fa-cogs" >
{ - headerId ? - : getHeader(onStartTutorial) - } + headerId ? + : getHeader(onStartTutorial) + }
{ menuId && ( diff --git a/src/ui/labels/add/AddLabelPage.js b/src/ui/labels/add/AddLabelPage.js index c3e7fe08d..043924f6b 100644 --- a/src/ui/labels/add/AddLabelPage.js +++ b/src/ui/labels/add/AddLabelPage.js @@ -1,36 +1,23 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; +import { Grid, Row, Col } from 'patternfly-react'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; import AddFormContainer from 'ui/labels/add/AddFormContainer'; import { ROUTE_LABELS_AND_LANGUAGES } from 'app-init/router'; import withPermissions from 'ui/auth/withPermissions'; import { SUPERUSER_PERMISSION } from 'state/permissions/const'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; export const AddLabelPageBody = () => ( + - - - - - - - - - - - - - - - - - - rows.map(item => {item.name} - + + ); +}; + +Wrapper.propTypes = { + children: PropTypes.func.isRequired, + active: PropTypes.bool, + onClick: PropTypes.func, +}.isRequired; diff --git a/src/ui/pages/add/PagesAddFormContainer.js b/src/ui/pages/add/PagesAddFormContainer.js index 44e23202b..95f08f297 100644 --- a/src/ui/pages/add/PagesAddFormContainer.js +++ b/src/ui/pages/add/PagesAddFormContainer.js @@ -30,21 +30,35 @@ const getNextPageProperty = ({ pattern, separator, }) => { - const indexes = pages - .map(page => page[property]) - .filter(Boolean) - .map((propertyValue) => { - const regex = new RegExp(`${pattern}[${separator}]*(?\\d)*$`); - const result = propertyValue.match(regex); - if (!result) { - return null; + // Regex to match the pattern with an optional number at the end. + const regex = new RegExp(`^${pattern}(?:${separator}(?\\d+))?$`); + let maxIndex = 0; // Assume no pages are found initially. + + pages.forEach((page) => { + const propertyValue = page[property]; + if (propertyValue) { + const match = propertyValue.match(regex); + if (match) { + if (match.groups.currentIndex) { + // If there's a number, parse it and compare. + const currentIndex = parseInt(match.groups.currentIndex, 10); + if (currentIndex > maxIndex) { + maxIndex = currentIndex; + } + } else { + // If there's no number, it's the base pattern. + maxIndex = Math.max(maxIndex, 1); + } } - const currentIndexStr = result.groups.currentIndex; - return currentIndexStr ? Number(currentIndexStr) : 1; - }) - .filter(Boolean); - const nextIndex = !indexes.length ? null : Math.max(...indexes) + 1; - return `${pattern}${nextIndex ? `${separator}${nextIndex}` : ''}`; + } + }); + + if (maxIndex === 0) { + // If no matching pages are found, return the base pattern. + return pattern; + } + // If matching pages are found, increment and return. + return `${pattern}${separator}${maxIndex + 1}`; }; export const getNextPageName = ({ pages, pattern, separator }) => getNextPageProperty({ diff --git a/src/ui/pages/add/PagesAddPage.js b/src/ui/pages/add/PagesAddPage.js index e0c792fc5..825725796 100644 --- a/src/ui/pages/add/PagesAddPage.js +++ b/src/ui/pages/add/PagesAddPage.js @@ -1,11 +1,10 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; +import { Grid, Row, Col } from 'patternfly-react'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import PagesAddFormContainer from 'ui/pages/add/PagesAddFormContainer'; import ErrorsAlertContainer from 'ui/common/form/ErrorsAlertContainer'; import AppTourContainer from 'ui/app-tour/AppTourContainer'; @@ -20,22 +19,13 @@ class PagesAddPage extends Component { render() { return ( + - - - - - - - - - - - - - - - diff --git a/src/ui/pages/clone/PagesClonePage.js b/src/ui/pages/clone/PagesClonePage.js index 737a03dba..7f943c38d 100644 --- a/src/ui/pages/clone/PagesClonePage.js +++ b/src/ui/pages/clone/PagesClonePage.js @@ -1,10 +1,9 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; +import { Grid, Row, Col } from 'patternfly-react'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import CloneFormContainer from 'ui/pages/clone/CloneFormContainer'; import ErrorsAlertContainer from 'ui/common/form/ErrorsAlertContainer'; import { ROUTE_PAGE_TREE } from 'app-init/router'; @@ -13,22 +12,13 @@ import { MANAGE_PAGES_PERMISSION } from 'state/permissions/const'; export const PagesClonePageBody = () => ( + - - - - - - - - - - - - - - - diff --git a/src/ui/pages/common/FindTemplateModal.js b/src/ui/pages/common/FindTemplateModal.js index 45165628b..2bd855ae9 100644 --- a/src/ui/pages/common/FindTemplateModal.js +++ b/src/ui/pages/common/FindTemplateModal.js @@ -1,11 +1,11 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -import { Modal, Col, Row, Spinner, DropdownKebab, MenuItem, Button } from 'patternfly-react'; - +import { Modal, Spinner, DropdownKebab, MenuItem, Button } from 'patternfly-react'; import GenericModalContainer from 'ui/common/modal/GenericModalContainer'; import { ROUTE_PAGE_TEMPLATE_DETAIL } from 'app-init/router'; -import { TEMPLATE_THUMBNAIL } from 'ui/pages/common/const'; +import Search from 'ui/common/Search'; +import PageTemplatePreview from 'ui/page-templates/list/PageTemplatePreview'; export const MODAL_ID = 'FindTemplateModal'; @@ -39,36 +39,29 @@ const FindTemplateModal = ({ pageTemplates .filter(({ code, descr }) => !searchValue || code.includes(searchValue) || descr.includes(searchValue)) - .map(({ code, descr }) => ( -
  • - - - { - const templatePath = ROUTE_PAGE_TEMPLATE_DETAIL.replace(':pageTemplateCode', code); - const link = `${global.location.href.split('/page')[0]}${templatePath}`; - window.open(link); - }} - > - - - -
    - {descr}
    -
  • +
    )) ); @@ -96,16 +89,10 @@ const FindTemplateModal = ({ modalCloseCleanup={handleModalClose} > - - - - - -
      - {renderRows()} -
    - -
    + +
    + {renderRows()} +
    ); diff --git a/src/ui/pages/common/PageSettingsForm.js b/src/ui/pages/common/PageSettingsForm.js index b40d26122..3e7e4566b 100644 --- a/src/ui/pages/common/PageSettingsForm.js +++ b/src/ui/pages/common/PageSettingsForm.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { Row, Col, OverlayTrigger, Popover, Spinner } from 'patternfly-react'; +import { Col, OverlayTrigger, Popover, Spinner } from 'patternfly-react'; import { FormattedMessage, injectIntl, intlShape, defineMessages } from 'react-intl'; import { Field, reduxForm } from 'redux-form'; @@ -8,6 +8,7 @@ import RenderRadioInput from 'ui/common/form/RenderRadioInput'; import SwitchRenderer from 'ui/common/form/SwitchRenderer'; import RenderSelectInput from 'ui/common/form/RenderSelectInput'; import FormLabel from 'ui/common/form/FormLabel'; +import Button from 'ui/common/Button'; const baseUrlMessages = defineMessages({ relative: { @@ -108,147 +109,134 @@ export class PageSettingsFormBody extends Component { - - -
    - - } - name="homePageCode" - mandatory - /> - - } - name="errorPageCode" - mandatory - /> - - } - name="loginPageCode" - mandatory - /> - - } - name="notFoundPageCode" - mandatory - /> -
    - -   - - - - - - - -
    - -
    - -   - - - - - - - - -   - - - - - - - -
    - -
    - -   - - - - -
    - -
    - - - - + +
    + } + name="homePageCode" + mandatory + /> + } + name="errorPageCode" + mandatory + /> + } + name="loginPageCode" + mandatory + /> + } + name="notFoundPageCode" + mandatory + /> +
    + +   + + + + + +
    -
    + + +
    - - - + + + + + + +
    +
    + +   + + + + + + + +
    +
    + +   + + + + +
    +
    + + + + +
    - - +
    +
    + + + +
    + - + ); } } @@ -265,7 +253,7 @@ PageSettingsFormBody.propTypes = { }; PageSettingsFormBody.defaultProps = { - onWillMount: () => {}, + onWillMount: () => { }, options: [], loading: false, }; diff --git a/src/ui/pages/common/PageStatusIcon.js b/src/ui/pages/common/PageStatusIcon.js index e3f15843c..c59c12673 100644 --- a/src/ui/pages/common/PageStatusIcon.js +++ b/src/ui/pages/common/PageStatusIcon.js @@ -1,7 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl, intlShape } from 'react-intl'; -import { PAGE_STATUS_DRAFT, PAGE_STATUS_PUBLISHED, PAGE_STATUS_UNPUBLISHED } from 'state/pages/const'; +import { + PAGE_STATUS_DRAFT, + PAGE_STATUS_PUBLISHED, + PAGE_STATUS_UNPUBLISHED, +} from 'state/pages/const'; const PageStatusIcon = ({ intl, status }) => { const msgs = defineMessages({ @@ -11,8 +15,11 @@ const PageStatusIcon = ({ intl, status }) => { }, }); const iconTitle = intl.formatMessage(msgs.pageStatus, {}); - const classNameAr = ['fa fa-circle PageStatusIcon', `PageStatusIcon--${status}`]; - return ; + const classNameAr = [ + 'PageStatusIcon', + `PageStatusIcon--${status}`, + ]; + return
    ; }; PageStatusIcon.propTypes = { @@ -20,7 +27,8 @@ PageStatusIcon.propTypes = { status: PropTypes.oneOf([ PAGE_STATUS_DRAFT, PAGE_STATUS_PUBLISHED, - PAGE_STATUS_UNPUBLISHED]).isRequired, + PAGE_STATUS_UNPUBLISHED, + ]).isRequired, }; export default injectIntl(PageStatusIcon); diff --git a/src/ui/pages/common/PageTree.js b/src/ui/pages/common/PageTree.js index 635fc8295..105d6c004 100644 --- a/src/ui/pages/common/PageTree.js +++ b/src/ui/pages/common/PageTree.js @@ -1,11 +1,9 @@ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { Spinner } from 'patternfly-react'; import { DDTable } from '@entando/ddtable'; import { DataTable } from '@entando/datatable'; - -import PageStatusIcon from 'ui/pages/common/PageStatusIcon'; import TreeNodeFolderIcon from 'ui/common/tree-node/TreeNodeFolderIcon'; import TreeNodeExpandedIcon from 'ui/common/tree-node/TreeNodeExpandedIcon'; import RowSpinner from 'ui/pages/common/RowSpinner'; @@ -17,6 +15,7 @@ import UnpublishPageModalContainer from 'ui/pages/common/UnpublishPageModalConta import PageListSearchTable from 'ui/pages/list/PageListSearchTable'; import MovePageModalContainer from 'ui/pages/common/MovePageModalContainer'; import { HOMEPAGE_CODE, PAGE_MOVEMENT_OPTIONS } from 'state/pages/const'; +import StatusBadge from './StatusBadge'; export const getIsRootAndVirtual = (page, virtualRootOn) => { @@ -51,20 +50,19 @@ class PageTree extends Component { onExpandAll, onCollapseAll, onExpandPage, - virtualRootOn, } = this.props; const columnDefs = { title: { Header: ( - +
    @@ -74,16 +72,16 @@ class PageTree extends Component { onKeyDown={onCollapseAll} role="button" tabIndex={-2} - className="PageTree PageTree__toggler" + className="PageTree" >
    - +
    ), attributes: { className: 'PageTree__thead-title', - style: { width: '70%' }, + style: { width: '65%' }, }, Cell: ({ row: { original: page, index } }) => { const onClickExpand = () => { @@ -92,60 +90,45 @@ class PageTree extends Component { } }; return ( - + - - {page.title} - + {page.title} ); }, cellAttributes: ({ row: page }) => { - const className = ['PageTree__tree-column-td']; + const className = ['PageTree__tree-column-td', 'PageTree__container']; // Remove arrow from page with no child if (page.isEmpty || page.original.isEmpty) { className.push('PageTree__tree-column-td--empty'); } // No drag class is added if first level child and Virtual Root On - if (page.original.parentCode === HOMEPAGE_CODE && virtualRootOn) { + if (page.original.parentCode === page.original.code) { className.push('PageTree__no-drag'); } - return { className: className.join(' ') }; + return { + className: className.join(' '), + style: { + marginLeft: (page.original.depth - 1) * 30 < 0 ? 0 : (page.original.depth - 1) * 30, + }, + }; }, }, status: { Header: , - attributes: { - className: 'text-center PageTree__thead', - style: { width: '10%' }, - }, + attributes: { className: 'PageTree__thead', style: { width: '15%' } }, Cell: this.renderStatusCell, - cellAttributes: { - className: 'text-center', - }, + cellAttributes: { className: 'text-center', style: { verticalAlign: 'middle' } }, }, displayedInMenu: { Header: , - attributes: { - className: 'text-center PageTree__thead', - style: { width: '10%' }, - }, + attributes: { className: 'PageTree__thead', style: { width: '15%' } }, Cell: ({ value }) => , - cellAttributes: { - className: 'text-center', - style: { verticalAlign: 'middle' }, - }, + cellAttributes: { style: { fontSize: '14px', verticalAlign: 'middle' } }, }, }; @@ -176,23 +159,25 @@ class PageTree extends Component { } return ( - +
    + +
    ); } @@ -200,7 +185,7 @@ class PageTree extends Component { const isRootAndVirtual = getIsRootAndVirtual(args.row.original, this.props.virtualRootOn); if (isRootAndVirtual) return null; return ( - + ); } @@ -213,21 +198,13 @@ class PageTree extends Component { } = this.props; const rowAction = { - Header: , - attributes: { - className: 'text-center', - width: '10%', - }, + Header:
    , + attributes: { className: 'text-center', width: '5%' }, Cell: this.renderActionCell, - cellAttributes: { - className: 'text-center', - }, + cellAttributes: { className: 'text-center', style: { verticalAlign: 'middle' } }, }; - if (searchPages) { - return ; - } - + if (searchPages) return ; const columns = this.getColumnDefs() || []; return ( @@ -240,8 +217,11 @@ class PageTree extends Component { columnResizable onColumnReorder={onSetColumnOrder} classNames={{ - table: 'PageTree table-hover table-treegrid', - row: 'PageTree__row', + table: 'PageTree table-hover table-treegrid table-bordered', + headerGroup: 'table-header', + row: 'PageTree__row table-row', + cell: 'table-cell', + }} rowReordering={{ onDrop: this.handleDrop, @@ -299,11 +279,11 @@ PageTree.propTypes = { PageTree.defaultProps = { pages: [], searchPages: null, - onDropPage: () => {}, - onExpandPage: () => {}, - onExpandAll: () => {}, - onCollapseAll: () => {}, - onSetColumnOrder: () => {}, + onDropPage: () => { }, + onExpandPage: () => { }, + onExpandAll: () => { }, + onCollapseAll: () => { }, + onSetColumnOrder: () => { }, columnOrder: ['title', 'status', 'displayedInMenu'], myGroupIds: [], virtualRootOn: false, diff --git a/src/ui/pages/common/PageTreeActionMenu.js b/src/ui/pages/common/PageTreeActionMenu.js index f4ed399bb..0d40d9028 100644 --- a/src/ui/pages/common/PageTreeActionMenu.js +++ b/src/ui/pages/common/PageTreeActionMenu.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { DropdownKebab, MenuItem } from 'patternfly-react'; -import { PAGE_STATUS_DRAFT, PAGE_STATUS_PUBLISHED, PAGE_STATUS_UNPUBLISHED } from 'state/pages/const'; +import { PAGE_STATUS_DRAFT, PAGE_STATUS_PUBLISHED, PAGE_STATUS_UNPUBLISHED, HOMEPAGE_CODE } from 'state/pages/const'; class PageTreeActionMenu extends Component { constructor(props) { @@ -24,14 +24,13 @@ class PageTreeActionMenu extends Component { return () => handler && handler(this.props.page, this.props.domain); } - render() { + renderPublishOrUnpublishMenuItem(disableDueToLackOfGroupAccess) { const { - page, onClickAdd, onClickEdit, onClickConfigure, onClickDetails, - onClickClone, onClickDelete, onClickPublish, onClickUnpublish, - onClickViewPublishedPage, onClickPreview, myGroupIds, isSearchMode, + page, onClickPublish, onClickUnpublish, isSearchMode, } = this.props; - - const disableDueToLackOfGroupAccess = !myGroupIds.includes(page.ownerGroup); + const isUnpublishedPage = page.status === PAGE_STATUS_UNPUBLISHED; + const hasUnpublishedParent = page.parentStatus === PAGE_STATUS_UNPUBLISHED; + const isHomepage = page.code === HOMEPAGE_CODE; let disabled = false; if (!page.isEmpty && page.status === PAGE_STATUS_PUBLISHED && !isSearchMode) { @@ -41,10 +40,11 @@ class PageTreeActionMenu extends Component { disabled = page.hasPublishedChildren; } - const disablePublishAction = (page.status === PAGE_STATUS_UNPUBLISHED && - page.parentStatus === PAGE_STATUS_UNPUBLISHED && !isSearchMode) - || disableDueToLackOfGroupAccess; - const changePublishStatus = page.status === PAGE_STATUS_PUBLISHED ? + const disablePublishAction = ( + isUnpublishedPage && hasUnpublishedParent && !isSearchMode && !isHomepage + ) || disableDueToLackOfGroupAccess; + + return page.status === PAGE_STATUS_PUBLISHED ? ( ); + } - const viewPublishedPage = page.status === PAGE_STATUS_PUBLISHED ? + renderViewPublishedPageMenuItem() { + const { page, onClickViewPublishedPage } = this.props; + return page.status === PAGE_STATUS_PUBLISHED ? ( ); + } - const disableDelete = !page.isEmpty || page.status === PAGE_STATUS_PUBLISHED || - page.status === PAGE_STATUS_DRAFT || disableDueToLackOfGroupAccess; - const renderDeleteItem = () => ( + renderDeleteMenuItem(disableDueToLackOfGroupAccess) { + const { page, onClickDelete } = this.props; + const isPublished = page.status === PAGE_STATUS_PUBLISHED; + const isHomepage = page.code === HOMEPAGE_CODE; + const hasStatusDraft = page.status === PAGE_STATUS_DRAFT; + + const disableDelete = !page.isEmpty || isPublished || isHomepage || + hasStatusDraft || disableDueToLackOfGroupAccess; + return ( ); + } + + render() { + const { + page, onClickAdd, onClickEdit, onClickConfigure, onClickDetails, + onClickClone, onClickPreview, myGroupIds, + } = this.props; + + const disableDueToLackOfGroupAccess = !myGroupIds.includes(page.ownerGroup); return (
    e.stopPropagation()} role="none" data-testid={`${page.code}-actions`}> - + - {changePublishStatus} + {this.renderPublishOrUnpublishMenuItem(disableDueToLackOfGroupAccess)} {onClickDetails && ( )} - {renderDeleteItem()} + {this.renderDeleteMenuItem(disableDueToLackOfGroupAccess)} - {viewPublishedPage} + {this.renderViewPublishedPageMenuItem()}
    ); diff --git a/src/ui/pages/common/PageTreeCompact.js b/src/ui/pages/common/PageTreeCompact.js index 56334d836..893e4842a 100644 --- a/src/ui/pages/common/PageTreeCompact.js +++ b/src/ui/pages/common/PageTreeCompact.js @@ -5,26 +5,43 @@ import { DropdownKebab, MenuItem } from 'patternfly-react'; import PageStatusIcon from 'ui/pages/common/PageStatusIcon'; import TreeNodeExpandedIcon from 'ui/common/tree-node/TreeNodeExpandedIcon'; import RowSpinner from 'ui/pages/common/RowSpinner'; -import { PAGE_STATUS_DRAFT, PAGE_STATUS_PUBLISHED, PAGE_STATUS_UNPUBLISHED } from 'state/pages/const'; +import { + PAGE_STATUS_DRAFT, + PAGE_STATUS_PUBLISHED, + PAGE_STATUS_UNPUBLISHED, +} from 'state/pages/const'; import { getIsRootAndVirtual } from './PageTree'; class PageTreeCompact extends Component { renderRows() { const { - pages, onClickDetails, onClickAdd, onClickEdit, onClickConfigure, - onClickClone, onClickDelete, onClickUnPublish, onClickPublish, - onRowClick, onClickViewPublishedPage, onClickPreview, selectedPage, - domain, locale, loadOnPageSelect, myGroupIds, virtualRootOn, + pages, + onClickDetails, + onClickAdd, + onClickEdit, + onClickConfigure, + onClickClone, + onClickDelete, + onClickUnPublish, + onClickPublish, + onRowClick, + onClickViewPublishedPage, + onClickPreview, + selectedPage, + domain, + locale, + loadOnPageSelect, + myGroupIds, + virtualRootOn, } = this.props; const handleClick = (handler, page) => (e) => { e.stopPropagation(); return handler && handler(page); }; - const handleClickViewPublishedPage = (handler, page) => - () => handler && handler(page, domain, locale); - const handleClickPreview = (handler, page) => - () => handler && handler(page, domain); + const handleClickViewPublishedPage = (handler, page) => () => + handler && handler(page, domain, locale); + const handleClickPreview = (handler, page) => () => handler && handler(page, domain); return pages.map((page, i) => { const disableDueToLackOfGroupAccess = !myGroupIds.includes(page.ownerGroup); const onClickExpand = () => { @@ -44,20 +61,24 @@ class PageTreeCompact extends Component { if (page.expanded) { disabled = page.hasPublishedChildren; } - const publishedDisabled = (page.status === PAGE_STATUS_UNPUBLISHED - && page.parentStatus === PAGE_STATUS_UNPUBLISHED) || disableDueToLackOfGroupAccess; - const changePublishStatus = page.status === PAGE_STATUS_PUBLISHED ? - ( + const publishedDisabled = + (page.status === PAGE_STATUS_UNPUBLISHED && + page.parentStatus === PAGE_STATUS_UNPUBLISHED) || + disableDueToLackOfGroupAccess; + const changePublishStatus = + page.status === PAGE_STATUS_PUBLISHED ? ( - ) : - ( + ) : ( ); - const viewPublishedPage = page.status === PAGE_STATUS_PUBLISHED ? - ( + const viewPublishedPage = + page.status === PAGE_STATUS_PUBLISHED ? ( - ) : - ( - + ) : ( + ); - const deletionDisabled = !page.isEmpty || page.status === PAGE_STATUS_PUBLISHED || - page.status === PAGE_STATUS_DRAFT || disableDueToLackOfGroupAccess; + const deletionDisabled = + !page.isEmpty || + page.status === PAGE_STATUS_PUBLISHED || + page.status === PAGE_STATUS_DRAFT || + disableDueToLackOfGroupAccess; const renderDeleteItem = () => ( (isRootAndVirtual ? null : onRowClick(page))} @@ -121,77 +145,82 @@ class PageTreeCompact extends Component { > {!loadOnPageSelect && ( - - {page.title} - + {page.title} )} {loadOnPageSelect && ( - - {page.title} - + {page.title} )}
    - { - isRootAndVirtual ? null : ( - - - - ) - } + {isRootAndVirtual ? null : ( + + + + )} - { - isRootAndVirtual ? null : ( -
    e.stopPropagation()} role="none"> - - - - - {onClickEdit && ( + {isRootAndVirtual ? null : ( +
    e.stopPropagation()} role="none"> + + + + + {onClickEdit && ( - )} - {onClickConfigure && ( + )} + {onClickConfigure && ( - )} - {onClickDetails && ( + )} + {onClickDetails && ( - )} - - - - {renderDeleteItem()} - {changePublishStatus} - - - - {viewPublishedPage} - -
    - - ) - } + )} + + + + {renderDeleteItem()} + {changePublishStatus} + + + + {viewPublishedPage} +
    +
    + )} - + ); }); } @@ -201,9 +230,7 @@ class PageTreeCompact extends Component { return ( - - {this.renderRows()} - + {this.renderRows()}
    ); } diff --git a/src/ui/pages/common/PageTreePreview.js b/src/ui/pages/common/PageTreePreview.js index 1a78509e0..09c9ca863 100644 --- a/src/ui/pages/common/PageTreePreview.js +++ b/src/ui/pages/common/PageTreePreview.js @@ -4,7 +4,7 @@ import TreeNodeFolderIcon from 'ui/common/tree-node/TreeNodeFolderIcon'; const PageTreePreview = ({ rowData }) => (
    - diff --git a/src/ui/pages/common/StatusBadge.js b/src/ui/pages/common/StatusBadge.js new file mode 100644 index 000000000..14b9e60d5 --- /dev/null +++ b/src/ui/pages/common/StatusBadge.js @@ -0,0 +1,40 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { defineMessages, injectIntl, intlShape } from 'react-intl'; +import { + PAGE_STATUS_DRAFT, + PAGE_STATUS_PUBLISHED, + PAGE_STATUS_UNPUBLISHED, +} from 'state/pages/const'; + +const StatusBadge = ({ intl, status }) => { + const msgs = defineMessages({ + pageStatus: { + id: `pages.status.${status}`, + defaultMessage: status, + }, + }); + const iconTitle = intl.formatMessage(msgs.pageStatus, {}); + const classNameAr = ['StatusBadge-circle', `StatusBadge-circle--${status}`]; + + return ( +
    + + {status} +
    + ); +}; + +StatusBadge.propTypes = { + intl: intlShape.isRequired, + status: PropTypes.oneOf([ + PAGE_STATUS_DRAFT, + PAGE_STATUS_PUBLISHED, + PAGE_STATUS_UNPUBLISHED, + ]).isRequired, +}; + +export default injectIntl(StatusBadge); diff --git a/src/ui/pages/config/ContentPages.js b/src/ui/pages/config/ContentPages.js index 40b293d57..21b5329c9 100644 --- a/src/ui/pages/config/ContentPages.js +++ b/src/ui/pages/config/ContentPages.js @@ -3,13 +3,14 @@ import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; import { FormattedMessage, injectIntl, intlShape, defineMessages } from 'react-intl'; import { ROUTE_PAGE_ADD, ROUTE_PAGE_CONFIG } from 'app-init/router'; -import { Spinner, Button } from 'patternfly-react'; +import { Spinner } from 'patternfly-react'; import PageTreeCompact from 'ui/pages/common/PageTreeCompact'; import DeletePageModalContainer from 'ui/pages/common/DeletePageModalContainer'; import PublishPageModalContainer from 'ui/pages/common/PublishPageModalContainer'; import UnpublishPageModalContainer from 'ui/pages/common/UnpublishPageModalContainer'; import PageListSearchTable from 'ui/pages/list/PageListSearchTable'; +import Button from 'ui/common/Button'; const msgs = defineMessages({ searchPlaceholder: { @@ -104,13 +105,29 @@ class ContentPages extends Component { render() { const { - loading, onExpandPage, pages, intl, searchPages, - onClear, loadOnPageSelect, onLoadPage, myGroupIds, + loading, + onExpandPage, + pages, + intl, + searchPages, + onClear, + loadOnPageSelect, + onLoadPage, + myGroupIds, virtualRootOn, } = this.props; const { expanded } = this.state; - const selectedPage = loadOnPageSelect ? this.props.selectedPage : this.state.selectedPage; + const selectedPage = loadOnPageSelect + ? this.props.selectedPage + : this.state.selectedPage; + + // const inputProps = { + // className: 'form-control', + // placeholder: intl.formatMessage(msgs.searchPlaceholder), + // onChange: this.handleSearchInputChange, + // onKeyDown: this.handleSearchInputKeyDown, + // }; return (
    @@ -129,8 +146,11 @@ class ContentPages extends Component {
    - - @@ -154,7 +174,9 @@ class ContentPages extends Component { role="button" tabIndex="0" > - +
    )} @@ -162,7 +184,9 @@ class ContentPages extends Component { {searchPages && searchPages.length ? ( {}} diff --git a/src/ui/pages/config/EmptyFrame.js b/src/ui/pages/config/EmptyFrame.js index 7638f3111..3ff5426b4 100644 --- a/src/ui/pages/config/EmptyFrame.js +++ b/src/ui/pages/config/EmptyFrame.js @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; - const EmptyFrame = ({ frameName, frameIsMainFrame, connectDropTarget, isOver, }) => { @@ -9,13 +8,20 @@ const EmptyFrame = ({ if (isOver) { classNameAr.push('EmptyFrame--drag-hover'); } - if (frameIsMainFrame) { - classNameAr.push('EmptyFrame--main-frame'); - } + const frameNameString = typeof frameName === 'string' ? frameName : ''; const component = ( -
    - { frameNameString } +
    + {frameNameString} + + {frameIsMainFrame && ( +
    + Main Frame +
    + )}
    ); if (connectDropTarget) { @@ -24,9 +30,7 @@ const EmptyFrame = ({ return component; }; - EmptyFrame.propTypes = { - frameName: PropTypes.string.isRequired, frameIsMainFrame: PropTypes.bool.isRequired, @@ -46,5 +50,4 @@ EmptyFrame.defaultProps = { isOver: false, }; - export default EmptyFrame; diff --git a/src/ui/pages/config/PageConfigGrid.js b/src/ui/pages/config/PageConfigGrid.js index fd027fec0..cf29499d7 100644 --- a/src/ui/pages/config/PageConfigGrid.js +++ b/src/ui/pages/config/PageConfigGrid.js @@ -16,7 +16,7 @@ const PageConfigGrid = ({ cellMap }) => { } return ( -
    +
    { content }
    ); diff --git a/src/ui/pages/config/PageConfigPage.js b/src/ui/pages/config/PageConfigPage.js index 1186e2b05..a77f49c6f 100644 --- a/src/ui/pages/config/PageConfigPage.js +++ b/src/ui/pages/config/PageConfigPage.js @@ -1,10 +1,24 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage, defineMessages, injectIntl, intlShape } from 'react-intl'; -import { Icon, Grid, Row, Col, Breadcrumb, DropdownButton, MenuItem, Alert, Spinner, Tabs, Tab } from 'patternfly-react'; -import { Panel, Button, ButtonToolbar } from 'react-bootstrap'; +import { + FormattedMessage, + defineMessages, + injectIntl, + intlShape, +} from 'react-intl'; +import { + Grid, + Row, + Col, + DropdownButton, + MenuItem, + Alert, + Spinner, + Tabs, + Tab, +} from 'patternfly-react'; +import { Panel, ButtonToolbar } from 'react-bootstrap'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import ErrorsAlertContainer from 'ui/common/form/ErrorsAlertContainer'; import PageStatusIcon from 'ui/pages/common/PageStatusIcon'; @@ -12,9 +26,16 @@ import PageConfigGridContainer from 'ui/pages/config/PageConfigGridContainer'; import ToolbarPageConfigContainer from 'ui/pages/config/ToolbarPageConfigContainer'; import SelectedPageInfoTableContainer from 'ui/pages/common/SelectedPageInfoTableContainer'; import AppTourContainer from 'ui/app-tour/AppTourContainer'; -import { APP_TOUR_STARTED } from 'state/app-tour/const'; -import { PAGE_STATUS_PUBLISHED, PAGE_STATUS_UNPUBLISHED } from 'state/pages/const'; import PagesEditFormContainer from 'ui/pages/edit/PagesEditFormContainer'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; +import Icon from 'ui/common/icon/Icon'; +import Button from 'ui/common/Button'; +import { APP_TOUR_STARTED } from 'state/app-tour/const'; +import { + PAGE_STATUS_PUBLISHED, + PAGE_STATUS_UNPUBLISHED, +} from 'state/pages/const'; +import { Settings, FilePen } from 'lucide-react'; const msgs = defineMessages({ appYes: { @@ -49,7 +70,8 @@ class PageConfigPage extends Component { this.toggleInfoTable = this.toggleInfoTable.bind(this); this.toggleEditingSettings = this.toggleEditingSettings.bind(this); this.openLinkPublishedPage = this.openLinkPublishedPage.bind(this); - this.handleToggleToolbarCollapse = this.handleToggleToolbarCollapse.bind(this); + this.handleToggleToolbarCollapse = + this.handleToggleToolbarCollapse.bind(this); } componentDidMount() { @@ -60,9 +82,10 @@ class PageConfigPage extends Component { componentWillReceiveProps(nextProps) { if (nextProps.pageStatus !== 'draft') { this.setState({ - statusChange: (nextProps.pageStatus !== this.props.pageStatus) ? - nextProps.pageStatus : - null, + statusChange: + nextProps.pageStatus !== this.props.pageStatus + ? nextProps.pageStatus + : null, }); } const { match, onWillMount } = this.props; @@ -101,7 +124,7 @@ class PageConfigPage extends Component { const { onSettingsCancel } = this.props; onSettingsCancel(); } - return ({ editingSettings: !editingSettings }); + return { editingSettings: !editingSettings }; }); } @@ -112,37 +135,31 @@ class PageConfigPage extends Component { } renderPageHeader() { - const { - pageName, pageStatus, pageDiffersFromPublished, - } = this.props; + const { pageName, pageStatus, pageDiffersFromPublished } = this.props; - const statusMessage = this.state.statusChange ? - ( - - - - ) : - null; + const statusMessage = this.state.statusChange ? ( + + + + ) : null; return (
    -

    +
    - {pageName} -

    +

    {pageName}

    +
    - - {statusMessage} - + {statusMessage}
    ); @@ -150,8 +167,14 @@ class PageConfigPage extends Component { renderActionBar(tab) { const { - intl, pageDiffersFromPublished, restoreConfig, previewUri, pageStatus, - onClickSaveSettings, pageSettingsButtonInvalid, pageSettingsButtonSubmitting, + intl, + pageDiffersFromPublished, + restoreConfig, + previewUri, + pageStatus, + onClickSaveSettings, + pageSettingsButtonInvalid, + pageSettingsButtonSubmitting, selectedPageForm, } = this.props; @@ -163,104 +186,118 @@ class PageConfigPage extends Component { - {tab === 'settings' ? + {tab === 'settings' ? ( - { - editingSettings && ( - - ) - } - - : ( -
    - + onClick={() => onClickSaveSettings(selectedPageForm)} + disabled={ + pageSettingsButtonInvalid || pageSettingsButtonSubmitting + } + > + + + + + )} + + ) : ( +
    + - - - - -
    - )} + + + + + +
    + )}
    @@ -269,9 +306,16 @@ class PageConfigPage extends Component { render() { const { - intl, pageIsOnTheFly, isOnTheFlyEnabled, - setSelectedPageOnTheFly, pageIsPublished, publishPage, unpublishPage, - applyDefaultConfig, pageConfigMatchesDefault, appTourProgress, + intl, + pageIsOnTheFly, + isOnTheFlyEnabled, + setSelectedPageOnTheFly, + pageIsPublished, + publishPage, + unpublishPage, + applyDefaultConfig, + pageConfigMatchesDefault, + appTourProgress, match, } = this.props; const { editingSettings, toolbarCollapsed } = this.state; @@ -282,17 +326,19 @@ class PageConfigPage extends Component { let defaultConfigBtn; if (pageConfigMatchesDefault) { defaultConfigBtn = ( -
    - - - - -
    + ); } else { defaultConfigBtn = ( - - - - - - - - + {!collapsed && ( + + + + + + + + + )}
    ); } } - ToolbarPageConfig.propTypes = { onWillMount: PropTypes.func, onWillUnmount: PropTypes.func, diff --git a/src/ui/pages/config/WidgetFrame.js b/src/ui/pages/config/WidgetFrame.js index 7301ec951..7ff0b0f3e 100644 --- a/src/ui/pages/config/WidgetFrame.js +++ b/src/ui/pages/config/WidgetFrame.js @@ -6,53 +6,71 @@ import { Link } from 'react-router-dom'; import { routeConverter } from '@entando/utils'; import { ROUTE_WIDGET_DETAIL, ROUTE_WIDGET_EDIT } from 'app-init/router'; -import { WIDGET_STATUS_MATCH, WIDGET_STATUS_DIFF, WIDGET_STATUS_REMOVED } from 'state/page-config/const'; +import { + WIDGET_STATUS_MATCH, + WIDGET_STATUS_DIFF, + WIDGET_STATUS_REMOVED, +} from 'state/page-config/const'; import WidgetIcon from 'ui/widgets/common/WidgetIcon'; - class WidgetFrame extends Component { render() { const { - widgetId, widgetName, widgetHasConfig, widgetStatus, frameId, frameName, frameIsMainFrame, - onClickDelete, connectDragSource, connectDropTarget, isOver, onClickSettings, onClickSaveAs, - configUiName, widgetHasConfigForm, + widgetId, + widgetName, + widgetHasConfig, + widgetStatus, + frameId, + frameName, + frameIsMainFrame, + onClickDelete, + connectDragSource, + connectDropTarget, + isOver, + onClickSettings, + onClickSaveAs, + configUiName, + widgetHasConfigForm, } = this.props; let actionsMenu = null; if (widgetStatus !== WIDGET_STATUS_REMOVED) { - const configMenuItems = widgetHasConfig && (configUiName || widgetHasConfigForm) ? - [ - ( + const configMenuItems = + widgetHasConfig && (configUiName || widgetHasConfigForm) + ? [ onClickSettings && onClickSettings(frameId)} > - - ), - ] : - null; - const cloneMenuItems = widgetHasConfig && configUiName ? [ - ( - onClickSaveAs && onClickSaveAs({ - widgetId, - widgetHasConfig, - frameId, - configUiName, - })} - > - - - ), - ] : null; + , + ] + : null; + const cloneMenuItems = + widgetHasConfig && configUiName + ? [ + + onClickSaveAs && + onClickSaveAs({ + widgetId, + widgetHasConfig, + frameId, + configUiName, + }) + } + > + + , + ] + : null; actionsMenu = ( @@ -75,7 +93,7 @@ class WidgetFrame extends Component { - { configMenuItems } + {configMenuItems} {cloneMenuItems} @@ -90,29 +108,64 @@ class WidgetFrame extends Component { } const classNameAr = ['WidgetFrame']; + const classNameInternalWidgetContent = ['WidgetFrame__content']; if (isOver) { classNameAr.push('WidgetFrame--drag-hover'); } - if (frameIsMainFrame) { - classNameAr.push('WidgetFrame--main-frame'); - } + // if (frameIsMainFrame) { + // classNameAr.push('WidgetFrame--main-frame'); + // } switch (widgetStatus) { - case WIDGET_STATUS_DIFF: classNameAr.push('WidgetFrame--status-diff'); break; - case WIDGET_STATUS_MATCH: classNameAr.push('WidgetFrame--status-match'); break; - case WIDGET_STATUS_REMOVED: classNameAr.push('WidgetFrame--status-removed'); break; - default: break; + case WIDGET_STATUS_DIFF: + classNameAr.push('WidgetFrame--status-diff'); + classNameInternalWidgetContent.push('WidgetFrame--status-diff'); + break; + case WIDGET_STATUS_MATCH: + classNameAr.push('WidgetFrame--status-match'); + classNameInternalWidgetContent.push('WidgetFrame--status-match'); + break; + case WIDGET_STATUS_REMOVED: + classNameAr.push('WidgetFrame--status-removed'); + classNameInternalWidgetContent.push('WidgetFrame--status-removed'); + break; + default: + break; } + let component = (
    -
    -
    - {frameName} -
    - { actionsMenu } -
    - - { widgetName } -
    +
    + {widgetStatus !== WIDGET_STATUS_MATCH && ( +
    +
    +
    +
    {frameName}
    + {frameIsMainFrame && ( +
    + Main Frame +
    + )} +
    + + {actionsMenu} +
    + )} + + {widgetStatus === WIDGET_STATUS_MATCH && ( +
    +
    +
    +
    + +
    + {widgetName} +
    + {actionsMenu} +
    + )}
    ); @@ -127,14 +180,16 @@ class WidgetFrame extends Component { } } - WidgetFrame.propTypes = { - frameName: PropTypes.string.isRequired, frameIsMainFrame: PropTypes.bool.isRequired, widgetName: PropTypes.string.isRequired, widgetHasConfig: PropTypes.bool, - widgetStatus: PropTypes.oneOf([WIDGET_STATUS_MATCH, WIDGET_STATUS_DIFF, WIDGET_STATUS_REMOVED]), + widgetStatus: PropTypes.oneOf([ + WIDGET_STATUS_MATCH, + WIDGET_STATUS_DIFF, + WIDGET_STATUS_REMOVED, + ]), configUiName: PropTypes.string, widgetHasConfigForm: PropTypes.bool, @@ -168,5 +223,4 @@ WidgetFrame.defaultProps = { widgetHasConfigForm: false, }; - export default WidgetFrame; diff --git a/src/ui/pages/config/WidgetGroupingItem.js b/src/ui/pages/config/WidgetGroupingItem.js index 3cedb5231..1a9346ed6 100644 --- a/src/ui/pages/config/WidgetGroupingItem.js +++ b/src/ui/pages/config/WidgetGroupingItem.js @@ -8,22 +8,30 @@ import WidgetIcon from 'ui/widgets/common/WidgetIcon'; const WidgetGroupingItem = ({ widgetId, widgetName, connectDragSource }) => { const component = ( -
    -
    -
    - -
    -
    -
    -
    - - {widgetName} - -
    -
    -
    + //
    + //
    + //
    + // + //
    + //
    + //
    + //
    + // + // {widgetName} + // + //
    + //
    + //
    + //
    + //
    +
    +
    + +
    +
    + + {widgetName} +
    ); @@ -34,7 +42,6 @@ const WidgetGroupingItem = ({ widgetId, widgetName, connectDragSource }) => { }; WidgetGroupingItem.propTypes = { - widgetName: PropTypes.string.isRequired, /* eslint-disable react/no-unused-prop-types */ diff --git a/src/ui/pages/config/WidgetGroupings.js b/src/ui/pages/config/WidgetGroupings.js index c5a2411e5..47d386753 100644 --- a/src/ui/pages/config/WidgetGroupings.js +++ b/src/ui/pages/config/WidgetGroupings.js @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl, intlShape } from 'react-intl'; import WidgetGrouping from 'ui/pages/config/WidgetGrouping'; +import Search from 'ui/common/Search'; export const GRID_VIEW = 'grid'; export const LIST_VIEW = 'list'; @@ -14,7 +15,13 @@ const msgs = defineMessages({ }); const WidgetGroupings = ({ - intl, groupedWidgets, widgetGroupingList, filterWidget, locale, searchFilter, clearFilter, + intl, + groupedWidgets, + widgetGroupingList, + filterWidget, + locale, + searchFilter, + clearFilter, }) => { const onChange = (event) => { filterWidget(event.target.value); @@ -22,23 +29,30 @@ const WidgetGroupings = ({ const [openGroupings, setOpenGroupings] = useState({}); const [view, setView] = useState(GRID_VIEW); - const toggleGroupingCollapse = grouping => setOpenGroupings({ - ...openGroupings, - [grouping]: !openGroupings[grouping], - }); + const toggleGroupingCollapse = grouping => + setOpenGroupings({ + ...openGroupings, + [grouping]: !openGroupings[grouping], + }); useEffect(() => { - const newOpenGroupings = widgetGroupingList.reduce((acc, curr, idx) => ({ - ...acc, - [curr]: !!searchFilter || idx === 0, - }), {}); + const newOpenGroupings = widgetGroupingList.reduce( + (acc, curr, idx) => ({ + ...acc, + [curr]: !!searchFilter || idx === 0, + }), + {}, + ); setOpenGroupings(newOpenGroupings); }, [searchFilter, widgetGroupingList]); - useEffect(() => () => { - clearFilter(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useEffect( + () => () => { + clearFilter(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, + [], + ); const optClassSel = 'WidgetGroupings__view-option--selected'; const gridViewClass = `fa fa-th WidgetGroupings__view-option @@ -49,15 +63,16 @@ const WidgetGroupings = ({ const setGridView = () => setView(GRID_VIEW); const setListView = () => setView(LIST_VIEW); + const inputProps = { + className: 'WidgetGroupings__input-pf-right-menu', + type: 'text', + onChange, + placeholder: intl.formatMessage(msgs.search), + }; return (
    - +
    - { - widgetGroupingList.map(grouping => ( - toggleGroupingCollapse(grouping)} - opened={openGroupings[grouping]} - name={grouping} - key={grouping} - view={view} - /> - )) - } + {widgetGroupingList.map(grouping => ( + toggleGroupingCollapse(grouping)} + opened={openGroupings[grouping]} + name={grouping} + key={grouping} + view={view} + /> + ))}
    ); diff --git a/src/ui/pages/detail/PagesDetailPage.js b/src/ui/pages/detail/PagesDetailPage.js index d6f74a8f9..397338c41 100644 --- a/src/ui/pages/detail/PagesDetailPage.js +++ b/src/ui/pages/detail/PagesDetailPage.js @@ -1,13 +1,13 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -import { Grid, Col, Row, Breadcrumb } from 'patternfly-react'; +import { Grid, Col, Row } from 'patternfly-react'; import { Panel, Button } from 'react-bootstrap'; import { ROUTE_HOME } from 'app-init/router'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import SelectedPageInfoTableContainer from 'ui/pages/common/SelectedPageInfoTableContainer'; import EmptyData from 'ui/fragments/detail/EmptyData'; @@ -33,26 +33,18 @@ class PagesDetailPage extends Component { return ( + - - - - - - - - - - - - - + - */} - - - - - - - - + ); }; diff --git a/src/ui/pages/list/PageTreePage.js b/src/ui/pages/list/PageTreePage.js index 6204b2d07..fb816ba4f 100644 --- a/src/ui/pages/list/PageTreePage.js +++ b/src/ui/pages/list/PageTreePage.js @@ -1,28 +1,32 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb, Button } from 'patternfly-react'; +import { Grid, Row, Col } from 'patternfly-react'; import { Link } from 'react-router-dom'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; import PageSearchForm from 'ui/pages/list/PageSearchForm'; import PageTreeContainer from 'ui/pages/common/PageTreeContainer'; import ErrorsAlertContainer from 'ui/common/form/ErrorsAlertContainer'; +import ModalPageSettings from 'ui/pages/settings/ModalPageSettings'; +import Button from 'ui/common/Button'; import AppTourContainer from 'ui/app-tour/AppTourContainer'; import { ROUTE_PAGE_ADD } from 'app-init/router'; import { withPermissionValues } from 'ui/auth/withPermissions'; +import Icon from 'ui/common/icon/Icon'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; + class PageTreePage extends Component { componentWillMount() { this.props.onWillMount(this.props); + this.setState({ open: false }); } renderButton() { if (this.props.search) { return ( - ); @@ -33,19 +37,8 @@ class PageTreePage extends Component { render() { return ( + - - - - - - - - - - - - @@ -57,17 +50,27 @@ class PageTreePage extends Component { - - + +
    + + +
    +
    {this.props.search && ( - - - {this.renderButton()} - - - )} + + + {this.renderButton()} + + + )} this.props.onNextStep(6)}>
    ); } return ( @@ -166,7 +121,7 @@ ProfileTypeListTable.propTypes = { }; ProfileTypeListTable.defaultProps = { - onDidMount: () => {}, + onDidMount: () => { }, loading: false, profiletypes: [], }; diff --git a/src/ui/reload-configuration/ReloadConfig.js b/src/ui/reload-configuration/ReloadConfig.js index 268873df6..849c4fdb2 100644 --- a/src/ui/reload-configuration/ReloadConfig.js +++ b/src/ui/reload-configuration/ReloadConfig.js @@ -19,7 +19,7 @@ const ReloadConfig = ({ onReload }) => ( - + diff --git a/src/ui/reload-configuration/ReloadConfigPage.js b/src/ui/reload-configuration/ReloadConfigPage.js index 015842063..be8329ef8 100644 --- a/src/ui/reload-configuration/ReloadConfigPage.js +++ b/src/ui/reload-configuration/ReloadConfigPage.js @@ -1,9 +1,8 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; +import { Grid, Row, Col } from 'patternfly-react'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import PageTitle from 'ui/internal-page/PageTitle'; import ReloadConfigContainer from 'ui/reload-configuration/ReloadConfigContainer'; import withPermissions from 'ui/auth/withPermissions'; @@ -12,19 +11,12 @@ import { SUPERUSER_PERMISSION } from 'state/permissions/const'; export const ReloadConfigPageBody = () => ( + - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - ( - - {role.name} - {role.code} - - - - - )); - } - renderTable() { const { roles, page, pageSize, intl, } = this.props; if (roles.length > 0) { - const pagination = { - page, - perPage: pageSize, - perPageOptions: [5, 10, 15, 25, 50], - }; + const pagination = { page, perPage: pageSize, perPageOptions: [5, 10, 15, 25, 50] }; - const messages = Object.keys(paginatorMessages).reduce((acc, curr) => ( - { ...acc, [curr]: intl.formatMessage(paginatorMessages[curr]) } - ), {}); + const columns = [ + { title: 'app.name', field: 'name', className: 'RoleListTable__th-lg' }, + { title: 'app.code', field: 'code', className: 'RoleListTable__th-lg' }, + { + title: '', + field: 'actions', + className: 'RoleListTable__th-xs text-center', + render: props => ( +
    + +
    + ), + }, + ]; return ( - - - - - - - - - - - {this.renderTableRows()} - -
    - -
    - + - +
    ); } return ( diff --git a/src/ui/user-profile/edit/EditUserProfilePage.js b/src/ui/user-profile/edit/EditUserProfilePage.js index e145df984..51aa20cc3 100644 --- a/src/ui/user-profile/edit/EditUserProfilePage.js +++ b/src/ui/user-profile/edit/EditUserProfilePage.js @@ -1,9 +1,8 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; +import { Grid, Row, Col } from 'patternfly-react'; import InternalPage from 'ui/internal-page/InternalPage'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import PageTitle from 'ui/internal-page/PageTitle'; import EditUserProfileFormContainer from 'ui/user-profile/edit/EditUserProfileFormContainer'; import { ROUTE_USER_LIST } from 'app-init/router'; @@ -12,22 +11,13 @@ import { EDIT_USER_PROFILES_PERMISSION } from 'state/permissions/const'; export const EditUserProfilePageBody = () => ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - diff --git a/src/ui/users/common/ProfileImageUploader.js b/src/ui/users/common/ProfileImageUploader.js index ae3a87b6b..87391d2dd 100644 --- a/src/ui/users/common/ProfileImageUploader.js +++ b/src/ui/users/common/ProfileImageUploader.js @@ -3,8 +3,7 @@ import PropTypes from 'prop-types'; import { Dropdown, MenuItem } from 'patternfly-react'; import { useDispatch } from 'react-redux'; import md5 from 'md5'; - -import { uploadFile } from 'state/file-browser/actions'; +import { uploadAvatar } from 'state/avatar/actions'; import { useDynamicResourceUrl } from 'hooks/useDynamicResourceUrl'; const FILE_BROWSER_PATH = 'static/profile'; @@ -15,16 +14,27 @@ const publicUrl = process.env.PUBLIC_URL; const toMd5 = string => md5(string.trim().toLowerCase()); const ProfileImageUploader = ({ - image, onChange, gravatarEmail, editable, + image, onChange, gravatarEmail, editable, useGravatar, onSetGravatar, }) => { const [edit, setEdit] = useState(false); const inputFileRef = useRef(null); + const imageRef = useRef(null); const dispatch = useDispatch(); const imageProvider = useDynamicResourceUrl(FILE_BROWSER_PATH); const onFileChange = ({ target: { files } }) => { - dispatch(uploadFile(files[0], FILE_BROWSER_PATH)).then(() => onChange(files[0].name)); + const file = files[0]; + if (file) { + dispatch(uploadAvatar(files[0])).then(() => { + const fr = new FileReader(); + fr.onload = () => { + imageRef.current.src = fr.result; + onChange(file.name); + }; + fr.readAsDataURL(file); + }); + } }; const handleUploadClick = () => { @@ -34,7 +44,7 @@ const ProfileImageUploader = ({ let userPicture = `${publicUrl}/images/user-icon.svg`; if (edit) { userPicture = `${publicUrl}/images/user-edit.svg`; - } else if (image === GRAVATAR && gravatarEmail) { + } else if (useGravatar && gravatarEmail) { userPicture = `${GRAVATAR_URL}/${toMd5(gravatarEmail)}`; } else if (image) { userPicture = `${imageProvider}/${image}`; @@ -52,12 +62,12 @@ const ProfileImageUploader = ({ className="ProfileImageUploader__file-upload" /> Upload Image - { gravatarEmail && onChange(GRAVATAR)}>Use Gravatar} + { gravatarEmail && onSetGravatar(GRAVATAR)}>Use Gravatar} onChange('')}>Remove Image @@ -69,13 +79,16 @@ ProfileImageUploader.propTypes = { image: PropTypes.string, gravatarEmail: PropTypes.string, onChange: PropTypes.func.isRequired, + onSetGravatar: PropTypes.func.isRequired, editable: PropTypes.bool, + useGravatar: PropTypes.bool, }; ProfileImageUploader.defaultProps = { image: '', gravatarEmail: '', editable: false, + useGravatar: false, }; export default ProfileImageUploader; diff --git a/src/ui/users/common/UserTable.js b/src/ui/users/common/UserTable.js new file mode 100644 index 000000000..da1b52e28 --- /dev/null +++ b/src/ui/users/common/UserTable.js @@ -0,0 +1,73 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { FormattedMessage, intlShape } from 'react-intl'; +import { Col, Paginator } from 'patternfly-react'; +import paginatorMessages from 'ui/paginatorMessages'; +import { TEST_ID_USER_LIST_TABLE } from 'ui/test-const/user-test-const'; + +const UserTable = (props) => { + const { + intl, columns, rows, pagination, totalItems, onChangePage, onChangePageSize, + } = props; + + const messages = Object.keys(paginatorMessages).reduce((acc, curr) => ( + { ...acc, [curr]: intl.formatMessage(paginatorMessages[curr]) } + ), {}); + + return ( + +
    + + + + {columns.map(({ title, className }) => ( + + ))} + + + + {rows.map(row => ( + + {columns.map(({ title, field, render }) => { + const value = () => (render ? render(row) : row[field] || ''); + return ; + })} + + ))} + +
    + {title ? : ''} +
    {value()}
    + +
    + + ); +}; + +UserTable.propTypes = { + intl: intlShape.isRequired, + columns: PropTypes.arrayOf(PropTypes.shape({ + title: PropTypes.string.isRequired, + field: PropTypes.string.isRequired, + className: PropTypes.string, + render: PropTypes.func, + })).isRequired, + rows: PropTypes.arrayOf(PropTypes.any.isRequired).isRequired, + pagination: PropTypes.shape({ + page: PropTypes.number.isRequired, + perPage: PropTypes.number.isRequired, + perPageOptions: PropTypes.arrayOf(PropTypes.number.isRequired), + }).isRequired, + totalItems: PropTypes.number.isRequired, + onChangePage: PropTypes.func.isRequired, + onChangePageSize: PropTypes.func.isRequired, +}; + +export default UserTable; diff --git a/src/ui/users/detail/DetailUserPage.js b/src/ui/users/detail/DetailUserPage.js index 86995a4c2..aab0a6156 100644 --- a/src/ui/users/detail/DetailUserPage.js +++ b/src/ui/users/detail/DetailUserPage.js @@ -1,10 +1,8 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; +import { Grid, Row, Col } from 'patternfly-react'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import { ROUTE_USER_LIST } from 'app-init/router'; import DetailUserTableContainer from 'ui/users/detail/DetailUserTableContainer'; import withPermissions from 'ui/auth/withPermissions'; @@ -12,22 +10,13 @@ import { VIEW_USERS_AND_PROFILES_PERMISSION } from 'state/permissions/const'; export const DetailUserPageBody = () => ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - - - - ( + - - - - - - - - - - - - ( /> - - + + diff --git a/src/ui/users/list/UserListTable.js b/src/ui/users/list/UserListTable.js index 182800f32..55c2df1ee 100644 --- a/src/ui/users/list/UserListTable.js +++ b/src/ui/users/list/UserListTable.js @@ -1,13 +1,12 @@ -import React, { Component } from 'react'; +import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import { Col, Paginator, Alert, Spinner } from 'patternfly-react'; +import { Col, Alert, Spinner } from 'patternfly-react'; import { FormattedMessage, defineMessages, injectIntl, intlShape } from 'react-intl'; import UserListMenuActions from 'ui/users/list/UserListMenuActions'; import UserStatus from 'ui/users/common/UserStatus'; import DeleteUserModalContainer from 'ui/users/common/DeleteUserModalContainer'; import { isEmpty } from 'lodash'; -import paginatorMessages from 'ui/paginatorMessages'; -import { TEST_ID_USER_LIST_TABLE } from 'ui/test-const/user-test-const'; +import UserTable from 'ui/users/common/UserTable'; const USER_INACTIVE = 'inactive'; @@ -31,91 +30,89 @@ class UserListTable extends Component { this.props.onWillMount({ page: 1, pageSize }); } - renderTableRows() { - const { users, intl } = this.props; - return users.map((user) => { - let userStatus = user.status; - if (!user.accountNotExpired && userStatus !== USER_INACTIVE) { - userStatus = 'accountExpired'; - } else if (!user.credentialsNotExpired && userStatus !== USER_INACTIVE) { - userStatus = 'passwordExpired'; - } - const msgs = defineMessages({ - userStatus: { - id: `user.table.status.${userStatus}`, - }, - }); - const profileType = user.profileType || {}; - return ( - - {user.username} - {profileType.typeDescription}{' '}{profileType.typeCode} - {user.profileAttributes.fullname} - {user.profileAttributes.email} - - - - - - - - ); - }); - } - renderTable() { const { users, page, pageSize, intl, } = this.props; if (users.length > 0) { - const pagination = { - page, - perPage: pageSize, - perPageOptions: [5, 10, 15, 25, 50], - }; + const pagination = { page, perPage: pageSize, perPageOptions: [5, 10, 15, 25, 50] }; - const messages = Object.keys(paginatorMessages).reduce((acc, curr) => ( - { ...acc, [curr]: intl.formatMessage(paginatorMessages[curr]) } - ), {}); + const columns = [ + { + title: 'user.table.username', + field: 'username', + }, + { + title: 'user.table.profileType', + field: 'profileType', + render: props => ( + props.profileType ? + + {props.profileType.typeDescription} + {props.profileType.typeCode && props.profileType.typeCode} + + : + ), + }, + { + title: 'user.table.fullname', + field: 'profileAttribute', + render: props => props.profileAttributes.fullname, + }, + { + title: 'user.table.email', + field: 'profileAttribute', + render: props => props.profileAttributes.email, + }, + { + title: 'user.table.status', + field: 'status', + className: 'UserListTable__th-sm text-center', + render: (props) => { + let userStatus = props.status; + if (!props.accountNotExpired && userStatus !== USER_INACTIVE) { + userStatus = 'accountExpired'; + } else if (!props.credentialsNotExpired && userStatus !== USER_INACTIVE) { + userStatus = 'passwordExpired'; + } + const msgs = defineMessages({ userStatus: { id: `user.table.status.${userStatus}` } }); + return ( +
    + +
    + ); + }, + }, + { + title: '', + field: 'actions', + className: 'UserListTable__th-xs text-center', + render: props => ( +
    + +
    + ), + }, + ]; return ( - - - - - - - - - - - - - - {this.renderTableRows()} - -
    - - - -
    - - + ); } return ( @@ -153,7 +150,7 @@ UserListTable.propTypes = { }; UserListTable.defaultProps = { - onWillMount: () => {}, + onWillMount: () => { }, loading: false, users: [], }; diff --git a/src/ui/users/list/UserSearchForm.js b/src/ui/users/list/UserSearchForm.js index 8ed3c2d3b..6bf9d13b0 100644 --- a/src/ui/users/list/UserSearchForm.js +++ b/src/ui/users/list/UserSearchForm.js @@ -44,12 +44,9 @@ export class UserSearchFormBody extends Component { const { intl } = this.props; return (
    -

    +

    - -
    @@ -283,6 +283,7 @@ MyProfileEditFormBody.propTypes = { onSubmit: PropTypes.func.isRequired, onCancel: PropTypes.func.isRequired, username: PropTypes.string.isRequired, + onSetGravatar: PropTypes.string.isRequired, profileTypesAttributes: PropTypes.arrayOf(PropTypes.shape({ type: PropTypes.string, code: PropTypes.string, @@ -321,15 +322,18 @@ MyProfileEditFormBody.propTypes = { id: PropTypes.string, typeCode: PropTypes.string, typeDescription: PropTypes.string, - profilepicture: PropTypes.string, }), onChangeProfilePicture: PropTypes.func.isRequired, + avatar: PropTypes.string, + useGravatar: PropTypes.bool, }; MyProfileEditFormBody.defaultProps = { profileTypesAttributes: [], userEmail: undefined, userProfileForm: {}, + avatar: '', + useGravatar: false, }; const MyProfileEditForm = reduxForm({ diff --git a/src/ui/users/my-profile/MyProfileEditFormContainer.js b/src/ui/users/my-profile/MyProfileEditFormContainer.js index 588d66b98..1731b466a 100644 --- a/src/ui/users/my-profile/MyProfileEditFormContainer.js +++ b/src/ui/users/my-profile/MyProfileEditFormContainer.js @@ -1,15 +1,17 @@ import { connect } from 'react-redux'; -import { reset, change } from 'redux-form'; +import { reset } from 'redux-form'; import { getUsername } from '@entando/apimanager'; import { fetchMyUserProfile, updateMyUserProfile } from 'state/user-profile/actions'; import { fetchLanguages } from 'state/languages/actions'; +import { fetchAvatar, removeAvatar, setGravatar } from 'state/avatar/actions'; import { getDefaultLanguage, getActiveLanguages } from 'state/languages/selectors'; -import { getSelectedProfileTypeAttributes } from 'state/profile-types/selectors'; +import { getSelectedProfileTypeAttributes, getUserProfileEmail } from 'state/profile-types/selectors'; import MyProfileEditForm from 'ui/users/my-profile/MyProfileEditForm'; import { getPayloadForForm } from 'helpers/entities'; -import { getUserProfile, getUserEmail } from 'state/user-profile/selectors'; +import { getUserProfile } from 'state/user-profile/selectors'; import { getUserProfileForm } from 'state/forms/selectors'; +import { getAvatarFilename, getUseGravatar } from 'state/avatar/selectors'; export const mapStateToProps = state => ({ username: getUsername(state), @@ -22,14 +24,17 @@ export const mapStateToProps = state => ({ getDefaultLanguage(state), getActiveLanguages(state), ), - userEmail: getUserEmail(state), + userEmail: getUserProfileEmail(state), userProfileForm: getUserProfileForm(state), + avatar: getAvatarFilename(state), + useGravatar: getUseGravatar(state), }); export const mapDispatchToProps = dispatch => ({ onMount: () => { dispatch(fetchLanguages({ page: 1, pageSize: 0 })); dispatch(fetchMyUserProfile()); + dispatch(fetchAvatar()); }, onSubmit: (userprofile) => { dispatch(updateMyUserProfile(userprofile, false)); @@ -37,7 +42,12 @@ export const mapDispatchToProps = dispatch => ({ onCancel: () => { dispatch(reset('UserProfile')); }, - onChangeProfilePicture: picture => dispatch(change('UserProfile', 'profilepicture', picture)), + onChangeProfilePicture: (picture) => { + if (picture === '') { + dispatch(removeAvatar()); + } + }, + onSetGravatar: () => dispatch(setGravatar()), }); export default connect( diff --git a/src/ui/users/my-profile/MyProfilePage.js b/src/ui/users/my-profile/MyProfilePage.js index ffe4581df..61f7b892b 100644 --- a/src/ui/users/my-profile/MyProfilePage.js +++ b/src/ui/users/my-profile/MyProfilePage.js @@ -1,15 +1,14 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage, defineMessages, injectIntl, intlShape } from 'react-intl'; -import { Row, Col, Breadcrumb, Tabs, Tab } from 'patternfly-react'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; +import { defineMessages, injectIntl, intlShape } from 'react-intl'; +import { Row, Col, Tabs, Tab } from 'patternfly-react'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; import ErrorsAlertContainer from 'ui/common/form/ErrorsAlertContainer'; import AccountFormContainer from 'ui/users/my-profile/AccountFormContainer'; import MyProfileEditFormContainer from 'ui/users/my-profile/MyProfileEditFormContainer'; import AppSettingsFormContainer from 'ui/users/my-profile/AppSettingsFormContainer'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; const msgs = defineMessages({ profile: { @@ -29,15 +28,12 @@ const MyProfilePage = ({ onTabSelect, intl }) => { return ( +
    -
    - - - - - -
    diff --git a/src/ui/users/restrictions/UserRestrictionsPage.js b/src/ui/users/restrictions/UserRestrictionsPage.js index cb48a5bfd..4602310bd 100644 --- a/src/ui/users/restrictions/UserRestrictionsPage.js +++ b/src/ui/users/restrictions/UserRestrictionsPage.js @@ -1,29 +1,20 @@ import React from 'react'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; -import { FormattedMessage } from 'react-intl'; - -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; +import { Grid, Row, Col } from 'patternfly-react'; import InternalPage from 'ui/internal-page/InternalPage'; import PageTitle from 'ui/internal-page/PageTitle'; import RestrictionsFormContainer from 'ui/users/restrictions/RestrictionsFormContainer'; import withPermissions from 'ui/auth/withPermissions'; import { SUPERUSER_PERMISSION } from 'state/permissions/const'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; export const UserRestrictionsPageBody = () => ( + - - - - - - - - - - - - ( +
    -
    -
    - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - -
    + +
    +
    -
    diff --git a/src/ui/widgets/clone/CloneWidgetPage.js b/src/ui/widgets/clone/CloneWidgetPage.js index 0ec02d4bd..7728320e2 100644 --- a/src/ui/widgets/clone/CloneWidgetPage.js +++ b/src/ui/widgets/clone/CloneWidgetPage.js @@ -1,10 +1,8 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; -import { Breadcrumb } from 'patternfly-react'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import InternalPage from 'ui/internal-page/InternalPage'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import PageTitle from 'ui/internal-page/PageTitle'; import CloneWidgetFormContainer from 'ui/widgets/clone/CloneWidgetFormContainer'; import ErrorsAlertContainer from 'ui/common/form/ErrorsAlertContainer'; @@ -18,31 +16,18 @@ class CloneWidgetPage extends Component { render() { return ( +
    -
    -
    - - - - - - - - - - - - {this.props.widgetName} - - -
    -
    -
    -
    -
    -
    - -
    + +
    +
    diff --git a/src/ui/widgets/common/IconUploader.js b/src/ui/widgets/common/IconUploader.js index ef8b44447..0e83de4df 100644 --- a/src/ui/widgets/common/IconUploader.js +++ b/src/ui/widgets/common/IconUploader.js @@ -74,7 +74,7 @@ const IconUploader = ({
    } -
    +
    + )) + } +
    +
    + + +
    + + + + {this.renderContent(this.state)} @@ -114,15 +197,15 @@ ListWidgetPage.propTypes = { }; ListWidgetPage.defaultProps = { - onWillMount: () => {}, - onDelete: () => {}, - onEdit: () => {}, - onNewUserWidget: () => {}, + onWillMount: () => { }, + onDelete: () => { }, + onEdit: () => { }, + onNewUserWidget: () => { }, locale: 'en', groupedWidgets: {}, widgetGroupingList: [], loading: false, - onSetColumnOrder: () => {}, + onSetColumnOrder: () => { }, columnOrder: [], }; diff --git a/src/ui/widgets/list/WidgetGridView.js b/src/ui/widgets/list/WidgetGridView.js new file mode 100644 index 000000000..a11a880ee --- /dev/null +++ b/src/ui/widgets/list/WidgetGridView.js @@ -0,0 +1,95 @@ +import React, { useMemo } from 'react'; +import PropTypes from 'prop-types'; +import { Col, DropdownKebab, MenuItem } from 'patternfly-react'; +import { FormattedMessage } from 'react-intl'; +import WidgetSectionTitle from 'ui/widgets/list/WidgetSectionTitle'; +import { withPermissionValues } from 'ui/auth/withPermissions'; +import { ROUTE_WIDGET_EDIT } from 'app-init/router'; +import CardList from 'ui/common/CardList'; +import Icon from 'ui/common/icon/Icon'; +import { colorDangerPrimary } from 'variables.scss'; + +export const WidgetGrid = ({ + title, + widgetList, + locale, + onDelete, + onEdit, + onNewUserWidget, + isSuperuser, +}) => { + const Actions = item => ( +
    + + {item.hasConfig && ( +
    + + onNewUserWidget(item.code)} + > + + +
    + )} +
    + + onEdit(item.code)} + > + + +
    + {!item.locked && item.used === 0 && ( +
    + + onDelete(item.code)} + > + + +
    + )} +
    +
    + ); + + const newWidgetList = useMemo(() => + widgetList.map(item => ( + { ...item, title: item.titles[locale], subtitle: item.code })), [locale, widgetList]); + const route = useMemo(() => ({ url: ROUTE_WIDGET_EDIT, type: 'widgetCode' }), []); + + return ( +
    + + : ''} + /> + + + +
    + ); +}; + +WidgetGrid.propTypes = { + title: PropTypes.string.isRequired, + widgetList: PropTypes.arrayOf(PropTypes.shape({})).isRequired, + locale: PropTypes.string.isRequired, + onDelete: PropTypes.func.isRequired, + onEdit: PropTypes.func.isRequired, + onNewUserWidget: PropTypes.func.isRequired, + isSuperuser: PropTypes.bool, +}; + +WidgetGrid.defaultProps = { + isSuperuser: true, +}; + +export default withPermissionValues(WidgetGrid); diff --git a/src/ui/widgets/list/WidgetListTable.js b/src/ui/widgets/list/WidgetListTable.js index b29f068c3..7cd9453a7 100644 --- a/src/ui/widgets/list/WidgetListTable.js +++ b/src/ui/widgets/list/WidgetListTable.js @@ -1,16 +1,16 @@ import React from 'react'; import PropTypes from 'prop-types'; - import { Col, DropdownKebab, MenuItem } from 'patternfly-react'; import { FormattedMessage } from 'react-intl'; import { DataTable } from '@entando/datatable'; import { routeConverter } from '@entando/utils'; import { Link } from 'react-router-dom'; - import WidgetSectionTitle from 'ui/widgets/list/WidgetSectionTitle'; import WidgetIcon from 'ui/widgets/common/WidgetIcon'; import { ROUTE_WIDGET_EDIT } from 'app-init/router'; import { withPermissionValues } from 'ui/auth/withPermissions'; +import Icon from 'ui/common/icon/Icon'; +import { colorDangerPrimary } from 'variables.scss'; export const WidgetListTableBody = ({ title, @@ -26,7 +26,7 @@ export const WidgetListTableBody = ({ const nameCell = (cellinfo) => { const { row: { original: item } } = cellinfo; return ( -
    +
       , - attributes: { - style: { width: '40%' }, - }, + attributes: { style: { width: '40%' } }, Cell: nameCell, }, code: { Header: , - attributes: { - style: { width: '40%' }, - }, + attributes: { style: { width: '40%' } }, }, used: { Header: , - attributes: { - className: 'text-center', - style: { width: '10%' }, - }, + attributes: { className: 'text-center', style: { width: '10%' } }, + cellAttributes: { className: 'text-center' }, }, }; - const columns = columnOrder.map(column => ({ - ...columnDefs[column], - accessor: column, - })); + const Actions = (item) => { + const { values: { code }, original: { used, locked, hasConfig } } = item; - const rowAction = isSuperuser ? ({ - Header: , - attributes: { - className: 'text-center', - style: { width: '10%' }, - }, - cellAttributes: { - className: 'text-center', - }, - Cell: (cellinfo) => { - const { values: { code, locked, hasConfig } } = cellinfo; - return ( -
    - - {hasConfig && ( - onNewUserWidget(code)} - > - - - )} + return ( +
    + + {hasConfig && ( +
    + + onNewUserWidget(code)} + > + + +
    + )} +
    + onEdit(code)} > - {!locked && ( - onDelete(code)} - > - - - )} - -
    - ); - }, +
    + {!locked && used === 0 && ( +
    + + onDelete(code)} + > + + +
    + )} +
    +
    + ); + }; + + const columns = columnOrder.map(column => ({ ...columnDefs[column], accessor: column })); + + const rowAction = isSuperuser ? ({ + Header: , + attributes: { className: 'text-center', style: { width: '10%' } }, + cellAttributes: { className: 'text-center' }, + Cell: cellinfo => Actions(cellinfo), }) : null; return (
    - + } + title={title ? : ''} /> @@ -146,7 +145,7 @@ WidgetListTableBody.propTypes = { WidgetListTableBody.defaultProps = { isSuperuser: true, - onSetColumnOrder: () => {}, + onSetColumnOrder: () => { }, columnOrder: [], }; diff --git a/src/ui/widgets/newUserWidget/NewUserWidgetFormContainer.js b/src/ui/widgets/newUserWidget/NewUserWidgetFormContainer.js index aef114bbd..0a4d1ddbf 100644 --- a/src/ui/widgets/newUserWidget/NewUserWidgetFormContainer.js +++ b/src/ui/widgets/newUserWidget/NewUserWidgetFormContainer.js @@ -3,7 +3,7 @@ import { withRouter } from 'react-router-dom'; import { routeConverter } from '@entando/utils'; import { submit } from 'redux-form'; import { clearErrors } from '@entando/messages'; -import WidgetForm from 'ui/widgets/common/WidgetForm'; +import WidgetForm, { MODE_ADD_NEW } from 'ui/widgets/common/WidgetForm'; import { fetchLanguages } from 'state/languages/actions'; import { getActiveLanguages } from 'state/languages/selectors'; @@ -22,6 +22,7 @@ import { ROUTE_WIDGET_LIST } from 'app-init/router'; import { ConfirmCancelModalID } from 'ui/common/cancel-modal/ConfirmCancelModal'; export const mapStateToProps = state => ({ + mode: MODE_ADD_NEW, groups: getGroupsList(state), parentWidget: getSelectedParentWidget(state), parentWidgetParameters: getSelectedParentWidgetParameters(state), diff --git a/src/ui/widgets/newUserWidget/NewUserWidgetPage.js b/src/ui/widgets/newUserWidget/NewUserWidgetPage.js index e4dba6cea..0fb03e369 100644 --- a/src/ui/widgets/newUserWidget/NewUserWidgetPage.js +++ b/src/ui/widgets/newUserWidget/NewUserWidgetPage.js @@ -1,10 +1,9 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Grid, Row, Col, Breadcrumb } from 'patternfly-react'; +import { Grid, Row, Col } from 'patternfly-react'; -import BreadcrumbItem from 'ui/common/BreadcrumbItem'; import PageTitle from 'ui/internal-page/PageTitle'; import InternalPage from 'ui/internal-page/InternalPage'; +import HeaderBreadcrumb from 'ui/internal-page/HeaderBreadcrumb'; import NewUserWidgetFormContainer from 'ui/widgets/newUserWidget/NewUserWidgetFormContainer'; import ErrorsAlertContainer from 'ui/common/form/ErrorsAlertContainer'; import { ROUTE_WIDGET_LIST } from 'app-init/router'; @@ -12,26 +11,19 @@ import withPermissions from 'ui/auth/withPermissions'; import { SUPERUSER_PERMISSION } from 'state/permissions/const'; export const NewUserWidgetPageBody = () => ( - + + - - - - - - - - - - - - - - - - + +
    + diff --git a/test/api/mfe.test.js b/test/api/mfe.test.js index 778166a45..920237bc9 100644 --- a/test/api/mfe.test.js +++ b/test/api/mfe.test.js @@ -1,10 +1,10 @@ import 'test/enzyme-init'; import { getMfeConfigList } from 'api/mfe'; -import { makeRequest, METHODS } from '@entando/apimanager'; -import { LIST_MFE_RESPONSE_OK } from 'test/mocks/mfe'; +import { makeMockRequest, METHODS } from '@entando/apimanager'; +import { LIST_MFE_MENU } from 'test/mocks/mfe'; jest.mock('@entando/apimanager', () => ({ - makeRequest: jest.fn(() => new Promise(resolve => resolve({}))), + makeMockRequest: jest.fn(() => new Promise(resolve => resolve({}))), METHODS: require.requireActual('@entando/apimanager').METHODS, })); @@ -20,11 +20,11 @@ describe('api/mfe', () => { it('makes the correct request', () => { getMfeConfigList(); - expect(makeRequest).toHaveBeenCalledWith({ + expect(makeMockRequest).toHaveBeenCalledWith({ uri: '/bundles/all/widgets?filters[0].value=app-builder&filters[0].attribute=widgetType&filters[0].operator=eq', domain: '/digital-exchange', method: METHODS.GET, - mockResponse: LIST_MFE_RESPONSE_OK, + mockResponse: LIST_MFE_MENU, useAuthentication: true, }); }); diff --git a/test/state/avatar/actions.test.js b/test/state/avatar/actions.test.js new file mode 100644 index 000000000..736ac0b6f --- /dev/null +++ b/test/state/avatar/actions.test.js @@ -0,0 +1,77 @@ +import { createFileObject, uploadAvatar, fetchAvatar } from 'state/avatar/actions'; +import * as actionsHelper from 'state/avatar/actions'; +import * as apiHelper from 'api/avatar'; + +describe('createFileObject', () => { + it('should create a file object', async () => { + const avatar = new File(['test data'], 'test.png', { type: 'image/png' }); + const result = await createFileObject(avatar); + expect(result).toEqual({ filename: 'test.png', base64: result.base64 }); + }); +}); + +describe('uploadAvatar', () => { + beforeAll(() => { + global.Date.now = jest.fn(() => new Date('2019-04-07T10:20:30Z').getTime()); + }); + it('should upload avatar successfully', async () => { + const avatar = new File(['test data'], 'test.png', { type: 'image/png' }); + const dispatch = jest.fn(); + jest.spyOn(actionsHelper, 'createFileObject').mockResolvedValue({ filename: 'test.png', base64: 'base64encodedstring' }); + jest.spyOn(apiHelper, 'postAvatar').mockResolvedValue({ json: () => Promise.resolve({ payload: { filename: 'test.png' } }) }); + + await uploadAvatar(avatar)(dispatch); + + expect(dispatch).toHaveBeenCalledWith({ payload: { id: 'uploadAvatar' }, type: 'loading/toggle-loading' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { filename: `test.png?${new Date('2019-04-07T10:20:30Z').getTime()}` }, type: 'avatar/filename' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { id: 'uploadAvatar' }, type: 'loading/toggle-loading' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { message: { id: 'fileBrowser.uploadFileComplete' }, type: 'success' }, type: 'toasts/add-toast' }); + expect(dispatch).toHaveBeenCalledTimes(5); + }); + + it('should handle avatar upload error', async () => { + const avatar = { name: 'test.jpg' }; + const dispatch = jest.fn(); + const error = new Error('Upload failed'); + jest.spyOn(actionsHelper, 'createFileObject').mockResolvedValue({ filename: avatar.name, base64: 'base64encodedstring' }); + jest.spyOn(apiHelper, 'postAvatar').mockRejectedValue(error); + + await uploadAvatar(avatar)(dispatch); + + expect(dispatch).toHaveBeenCalledWith({ payload: { id: 'uploadAvatar' }, type: 'loading/toggle-loading' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { id: 'uploadAvatar' }, type: 'loading/toggle-loading' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { message: { id: 'fileBrowser.uploadFileError', values: { errmsg: TypeError('[TypeError: Failed to execute \'readAsDataURL\' on \'FileReader\': parameter 1 is not of type \'Blob\'.]') } }, type: 'error' }, type: 'toasts/add-toast' }); + expect(dispatch).toHaveBeenCalledWith({ type: 'errors/add-errors', payload: { errors: TypeError('[TypeError: Failed to execute \'readAsDataURL\' on \'FileReader\': parameter 1 is not of type \'Blob\'.]') } }); + expect(dispatch).toHaveBeenCalledTimes(4); + }); +}); + + +describe('fetchAvatar', () => { + beforeAll(() => { + global.Date.now = jest.fn(() => new Date('2019-04-07T10:20:30Z').getTime()); + }); + + it('should retrieve the avatar successfully', async () => { + const dispatch = jest.fn(); + jest.spyOn(apiHelper, 'getAvatar').mockResolvedValue({ ok: true, json: () => Promise.resolve({ payload: { filename: 'test.png', useGravatar: false } }) }); + await fetchAvatar()(dispatch); + expect(dispatch).toHaveBeenCalledWith({ payload: { id: 'fetchAvatar' }, type: 'loading/toggle-loading' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { useGravatar: false }, type: 'avatar/useGravatar' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { filename: `test.png?${new Date('2019-04-07T10:20:30Z').getTime()}` }, type: 'avatar/filename' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { id: 'fetchAvatar' }, type: 'loading/toggle-loading' }); + expect(dispatch).toHaveBeenCalledTimes(4); + }); + + it('should handle avatar fetch error', async () => { + const dispatch = jest.fn(); + const error = new Error('Fetch failed'); + jest.spyOn(apiHelper, 'getAvatar').mockRejectedValue(error); + await fetchAvatar()(dispatch); + expect(dispatch).toHaveBeenCalledWith({ payload: { id: 'fetchAvatar' }, type: 'loading/toggle-loading' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { id: 'fetchAvatar' }, type: 'loading/toggle-loading' }); + expect(dispatch).toHaveBeenCalledWith({ payload: { message: 'Fetch failed', type: 'error' }, type: 'toasts/add-toast' }); + expect(dispatch).toHaveBeenCalledTimes(4); + }); +}); + diff --git a/test/state/avatar/reducer.test.js b/test/state/avatar/reducer.test.js new file mode 100644 index 000000000..c5eaeb895 --- /dev/null +++ b/test/state/avatar/reducer.test.js @@ -0,0 +1,26 @@ +import { createStore } from 'redux'; +import rootReducer from 'state/rootReducer'; +import { SET_AVATAR_FILE_NAME } from 'state/avatar/types'; + +describe('avatarReducer', () => { + it('should handle SET_AVATAR_FILE_NAME action', () => { + const store = createStore(rootReducer); + const setAvatarFileNameAction = { + type: SET_AVATAR_FILE_NAME, + payload: { filename: 'test.jpg' }, + }; + store.dispatch(setAvatarFileNameAction); + expect(store.getState().avatar.filename).toBe('test.jpg'); + }); + + it('should handle unknown action type', () => { + const store = createStore(rootReducer); + const unknownAction = { + type: 'UNKNOWN_ACTION', + payload: { filename: 'test.jpg' }, + }; + store.dispatch(unknownAction); + expect(store.getState().avatar.filename).toBe(''); + }); +}); + diff --git a/test/state/avatar/selectors.test.js b/test/state/avatar/selectors.test.js new file mode 100644 index 000000000..a00157edb --- /dev/null +++ b/test/state/avatar/selectors.test.js @@ -0,0 +1,31 @@ +import { createStore } from 'redux'; +import { getAvatar, getAvatarFilename, getUseGravatar } from 'state/avatar/selectors'; +import rootReducer from 'state/rootReducer'; + +describe('getAvatar', () => { + it('should return the avatar state', () => { + const initialState = { avatar: { filename: 'test.jpg', useGravatar: false } }; + const store = createStore(rootReducer, initialState); + const result = getAvatar(store.getState()); + expect(result).toEqual(initialState.avatar); + }); +}); + +describe('getAvatarFilename selector', () => { + it('should return the avatar filename', () => { + const initialState = { avatar: { filename: 'test.jpg', useGravatar: false } }; + const store = createStore(rootReducer, initialState); + const result = getAvatarFilename(store.getState()); + expect(result).toBe('test.jpg'); + }); +}); + +describe('getUseGravatar selector', () => { + it('should return the useGravatar value', () => { + const initialState = { avatar: { filename: 'test.jpg', useGravatar: false } }; + const store = createStore(rootReducer, initialState); + const result = getUseGravatar(store.getState()); + expect(result).toBeFalsy(); + }); +}); + diff --git a/test/state/profile-types/actions.test.js b/test/state/profile-types/actions.test.js index e26817bc6..92ccd247c 100644 --- a/test/state/profile-types/actions.test.js +++ b/test/state/profile-types/actions.test.js @@ -65,6 +65,7 @@ import { handlerAttributeFromProfileType, sendMoveAttributeUp, sendMoveAttributeDown, + excludeTypes, } from 'state/profile-types/actions'; import { postProfileType, @@ -526,7 +527,7 @@ describe('state/profile-types/actions ', () => { expect(actions[1]).toHaveProperty('type', SET_ATTRIBUTES); expect(actions[1]).toHaveProperty('payload'); expect(actions[1]).toHaveProperty('payload.attributes'); - expect(actions[1]).toHaveProperty('payload.attributes', PROFILE_TYPES_ATTRIBUTES); + expect(actions[1]).toHaveProperty('payload.attributes', PROFILE_TYPES_ATTRIBUTES.filter(att => !excludeTypes.includes(att))); expect(actions[2]).toHaveProperty('type', TOGGLE_LOADING); done(); }).catch(done.fail); diff --git a/test/state/profile-types/selectors.test.js b/test/state/profile-types/selectors.test.js index 17e2ea87b..fd9e79205 100644 --- a/test/state/profile-types/selectors.test.js +++ b/test/state/profile-types/selectors.test.js @@ -22,6 +22,7 @@ import { getMonolistAttributeType, getIsMonolistCompositeAttributeType, getNewAttributeComposite, + getUserProfileEmail, } from 'state/profile-types/selectors'; const TEST_STATE = { @@ -235,4 +236,46 @@ describe('state/users/selectors', () => { const res = getNewAttributeComposite(LIST_SELECTED4); expect(res).toEqual('boi'); }); + + describe('getUserProfileEmail selector', () => { + it('should return undefined if selectedUserProfileAttributes is falsy', () => { + const result = getUserProfileEmail({ + profileTypes: { selected: null }, userProfile: { attributes: [] }, + }); + expect(result).toBeUndefined(); + }); + + it('should return undefined if userProfile is falsy', () => { + const result = getUserProfileEmail({ profileTypes: { selected: [{ roles: [{ code: 'userprofile:email' }] }] }, userProfile: { attributes: [] } }); + expect(result).toBeUndefined(); + }); + + it('should return undefined if emailAttribute is not found', () => { + const result = getUserProfileEmail({ + profileTypes: { selected: [] }, userProfile: { attributes: [] }, + }); + expect(result).toBeUndefined(); + }); + + it('should return undefined if userProfileEmailAttribute is not found', () => { + const result = getUserProfileEmail({ profileTypes: { selected: { attributes: [{ roles: [{ code: 'invalid-role-code' }] }] } }, userProfile: { attributes: [] } }); + expect(result).toBeUndefined(); + }); + + it('should return userProfileEmailAttribute.value if all conditions are met', () => { + const selectedUserProfileAttributes = [{ code: 'email', roles: [{ code: 'userprofile:email' }] }]; + const userProfile = { + attributes: [ + { code: 'email', value: 'test@example.com' }, + { code: 'other-attribute', value: 'other-value' }, + ], + }; + + const result = getUserProfileEmail({ + profileTypes: { selected: { attributes: selectedUserProfileAttributes } }, userProfile, + }); + expect(result).toBe('test@example.com'); + }); + }); }); + diff --git a/test/test/mocks/mfe.js b/test/test/mocks/mfe.js index 383ea5ca1..1f15147ef 100644 --- a/test/test/mocks/mfe.js +++ b/test/test/mocks/mfe.js @@ -175,3 +175,28 @@ export const UPDATE_MFE_OK = { }, }, }; + +export const LIST_MFE_MENU = [ + { + id: '9e343527-37bf-472e-aadc-a780613ceb88', + bundleId: '64c57c33', + bundleCode: 'layout-core-bundle-id', + bundleGroup: 'layout-core-bundle', + widgetName: 'app-builder-menu', + widgetCode: '6e3e752a-f796-11ec-b939-0242ac120002', + assets: ['menu/app-builder-menu.umd.js'], + customElement: 'app-builder-menu', + descriptorExt: { + slot: 'primary-menu', + nav: [], + paths: [], + }, + systemParams: { + api: { + navigation: { + url: 'http://localhost:8080', + }, + }, + }, + }, +]; diff --git a/test/ui/pages/add/PagesAddFormContainer.test.js b/test/ui/pages/add/PagesAddFormContainer.test.js index aa477830f..64bcdf576 100644 --- a/test/ui/pages/add/PagesAddFormContainer.test.js +++ b/test/ui/pages/add/PagesAddFormContainer.test.js @@ -200,6 +200,14 @@ describe('getNextPageCode', () => { separator: '_', })).toBe('hello_world_app_3'); }); + + it('hello_world_app_11', () => { + expect(getNextPageCode({ + pages: [{ code: 'hello_world_app_10' }], + pattern: 'hello_world_app', + separator: '_', + })).toBe('hello_world_app_11'); + }); }); describe('PagesAddFormContainer', () => {