From 9eb0f6de50e1a0930c1bc5916868bf41f61986e5 Mon Sep 17 00:00:00 2001 From: rmocanu-ionos Date: Tue, 26 Sep 2023 15:34:53 +0000 Subject: [PATCH] CI Build Artifacts --- assets/ionoscloud/ionoscloud-0.1.1.tgz | Bin 0 -> 1923 bytes charts/ionoscloud/0.1.1/Chart.yaml | 16 ++++ charts/ionoscloud/0.1.1/README.md | 0 charts/ionoscloud/0.1.1/files/nginx.conf | 17 ++++ .../ionoscloud/0.1.1/templates/_helpers.tpl | 78 ++++++++++++++++++ charts/ionoscloud/0.1.1/templates/cr.yaml | 14 ++++ charts/ionoscloud/0.1.1/values.yaml | 30 +++++++ extensions/ionoscloud/0.1.1/files.txt | 13 +++ .../plugin/ionoscloud-0.1.1.umd.min.5.js | 2 + .../plugin/ionoscloud-0.1.1.umd.min.5.js.map | 1 + ...noscloud-0.1.1.umd.min.cloud-credential.js | 2 + ...loud-0.1.1.umd.min.cloud-credential.js.map | 1 + .../0.1.1/plugin/ionoscloud-0.1.1.umd.min.js | 2 + .../plugin/ionoscloud-0.1.1.umd.min.js.map | 1 + ...ionoscloud-0.1.1.umd.min.machine-config.js | 2 + ...scloud-0.1.1.umd.min.machine-config.js.map | 1 + ...vendors~cloud-credential~machine-config.js | 10 +++ ...ors~cloud-credential~machine-config.js.map | 1 + ...ud-0.1.1.umd.min.vendors~machine-config.js | 40 +++++++++ ....1.1.umd.min.vendors~machine-config.js.map | 1 + .../ionoscloud/0.1.1/plugin/package.json | 20 +++++ index.yaml | 12 +-- 22 files changed, 258 insertions(+), 6 deletions(-) create mode 100644 assets/ionoscloud/ionoscloud-0.1.1.tgz create mode 100644 charts/ionoscloud/0.1.1/Chart.yaml create mode 100644 charts/ionoscloud/0.1.1/README.md create mode 100644 charts/ionoscloud/0.1.1/files/nginx.conf create mode 100644 charts/ionoscloud/0.1.1/templates/_helpers.tpl create mode 100644 charts/ionoscloud/0.1.1/templates/cr.yaml create mode 100644 charts/ionoscloud/0.1.1/values.yaml create mode 100644 extensions/ionoscloud/0.1.1/files.txt create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.5.js create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.5.js.map create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js.map create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.js create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.js.map create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.machine-config.js create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.machine-config.js.map create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.vendors~cloud-credential~machine-config.js create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.vendors~cloud-credential~machine-config.js.map create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.vendors~machine-config.js create mode 100644 extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.vendors~machine-config.js.map create mode 100644 extensions/ionoscloud/0.1.1/plugin/package.json diff --git a/assets/ionoscloud/ionoscloud-0.1.1.tgz b/assets/ionoscloud/ionoscloud-0.1.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4587a2128c7bb43227ef9c96be0044357b544bcc GIT binary patch literal 1923 zcmV-}2YmP+iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PI;?ZyUK4_VfIT1GS4ywi#+9%l2ZjTOe?PHfT3%#OUtBVqs96 zGb6$ra+c)CRu%vEf)`1nu@WV%>$F+X52koIJQwmim*Gk(!-Q&!;rWbeOBS>iM-SVw zEXz(O6aPQUvi|?k_;_?Qnw(^lle5X$Np_Ttj*m~yjv#wrK6bX&SgMb*|M;xFaQ`Qb zN~tWhTuGBB0E}8HR7DuIRv_VO$WU8eax8MtRI(ZBoy)Gy6)FIw@O;0X(+=S!eH9+v=ME^Woj12V!d;lGC2q?+uNP94eFX(lde}i zgBvajbz^oekD_f$FeYbFfHC<1|AwgsbEv7L71k*2&Q&c>nW`HlQQ91WcqX9@|7msP ze4NmxS^vz)h>Vf~4b!}_e&|I}82Ev*8J7s>N|w9=DhoJw?-$NB7D%P#R2V3g20KI8 zyzh?r3eD%J6V4pbnYE3{heJ(oNX6}}owf!wQ_`ZegsFPyX`}%pTAt#qMd^4nX$L)O z%H^=Ru7;g4-z8>VCC8T)~z72-k(&K5bmF5f77q0t1)HyGgb67?K)z9My>!!7jcfY&|FUWgmIFdGR1Bmo%IbIu~=0Ac5%H5T>j zi$Fwao5QzR+^Q?I7jeiB7T5^2a86>)odZCVgCnoes8%yHIV|t|ajezcF3ueo-`Y4T zRe_f%kXfbUkW~V8^x{ry0JJQ*bz z=O9QjI6d}VUSGCl$!}qh4j|G(S-5WEc|6xhEdpJi;2gmMeru`l>4}RaJ@+K}83S#< z-ntWXhxDYT!XpQ630QJmAZuh8nHN`4kbnR2X5H|()Pq20xLxMssOP7<^^YugsuFD;)aq zmuz=;>*{rE>RwB9oz9-#uJMwDRf0}Y?6s|5yD@BEpsub%KPHFp&Ib;ZAq@UBfWg(^ z)1Q;7Yb67pW*?tnRbX_6q9$fG^t|V=TmqL&w8i^`BjNb>tuir?`FlKqbZ$@-`o%ga zc5}38$o2Z|y3Bf=I4+kvw!DMiT4k}Pg!@!N`d*~dMIf}gO_w3$+o{A=6!wv7?8}<& zWF(}@@7GuW1F~BRE{&y<;kFFjC$|w`!)6Hgui_)W(lOxQ2{|EQSQR#QCJH+)^lRv_=HQ4n zbjk&{91U^qGd?l$7j9Rt&C!{nrM+vpsnu;+^@EFcnD}!COJ88y8UHi=pjDu~_5aDZ z7ynPr#^Xc${}`=@?!ncNSSAQQW>cZQU)7$El4~xD9RBh8!f#D#w6vg><_W+)SGI|5 zy*mpV;-`SV|MJ6ORq(bSA}rR?#5<5&7AP%D+-4WIJI-Q71pWYK=JA|MZaH-sMX7}I z0xp&-(C|vG(xJbisA2PwEM^SPqC+USVXZMxtAdvcmm|2`!54WxSqv0_r)R!iRp;qb@}uSzmsG6iqbwT5rG2pSe>F=RTA>+krn_GPRt2<9ZOIvUo9#H& zi&Q@M3;D8J$3|~oy?FVOMk93Q^_JW9hkN^4+wmpDfN%kcRJW#MiEDET}NI7by{T@&0`l=m_Ga+T@& zq?v5KfWY0|^ZxE%^8DBQ6G^OTXf#SVrZVFHHq>crmGk+xp8fT3km1VLZ?2yAhpoCs zX+V`__Y9>h3}>pw;g-i<{fb`FY^YWL= 1.16.0-0 < 1.28.0-0' + catalog.cattle.io/namespace: cattle-ui-plugin-system # Must prefix with cattle- and suffix with -system= + catalog.cattle.io/os: linux + catalog.cattle.io/permits-os: linux, windows + catalog.cattle.io/rancher-version: '>= 2.7.0-0 < 2.8.0-0' + catalog.cattle.io/scope: management + catalog.cattle.io/ui-component: plugins +apiVersion: v2 +appVersion: "0.1.1" +description: Adds Machine Config and Cloud Credeantials for the ionoscloud rancher driver +name: ionoscloud +type: application +version: 0.1.1 +icon: https://raw.githubusercontent.com/ionos-cloud/ui-extensions-ionoscloud/main/pkg/ionoscloud/ionos.svg diff --git a/charts/ionoscloud/0.1.1/README.md b/charts/ionoscloud/0.1.1/README.md new file mode 100644 index 0000000..e69de29 diff --git a/charts/ionoscloud/0.1.1/files/nginx.conf b/charts/ionoscloud/0.1.1/files/nginx.conf new file mode 100644 index 0000000..07a20f4 --- /dev/null +++ b/charts/ionoscloud/0.1.1/files/nginx.conf @@ -0,0 +1,17 @@ +events {} +http { + sendfile on; + server { + listen {{ .Values.pluginServer.service.targetPort }}; + listen [::]:{{ .Values.pluginServer.service.targetPort }}; + + resolver 0.0.0.0; + autoindex on; + + server_name _; + server_tokens off; + + root /home/plugin-server/plugin-contents; + gzip_static on; + } +} diff --git a/charts/ionoscloud/0.1.1/templates/_helpers.tpl b/charts/ionoscloud/0.1.1/templates/_helpers.tpl new file mode 100644 index 0000000..bc15dc4 --- /dev/null +++ b/charts/ionoscloud/0.1.1/templates/_helpers.tpl @@ -0,0 +1,78 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "plugin-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "plugin-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "plugin-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "plugin-server.labels" -}} +helm.sh/chart: {{ include "plugin-server.chart" . }} +{{ include "plugin-server.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "plugin-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "plugin-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- else -}} +{{- "" -}} +{{- end -}} +{{- end -}} + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector" -}} +{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} +beta.kubernetes.io/os: linux +{{- else -}} +kubernetes.io/os: linux +{{- end -}} +{{- end -}} diff --git a/charts/ionoscloud/0.1.1/templates/cr.yaml b/charts/ionoscloud/0.1.1/templates/cr.yaml new file mode 100644 index 0000000..3214ff4 --- /dev/null +++ b/charts/ionoscloud/0.1.1/templates/cr.yaml @@ -0,0 +1,14 @@ +{{- if .Values.plugin.enabled }} +apiVersion: catalog.cattle.io/v1 +kind: UIPlugin +metadata: + name: {{ include "plugin-server.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: {{ include "plugin-server.labels" . | nindent 4 }} +spec: + plugin: # should initially follow the design of the Helm Chart.yaml fields, could discuss modifying this + name: {{ include "plugin-server.fullname" . }} + version: {{ (semver (default .Chart.AppVersion .Values.plugin.versionOverride)).Original }} + endpoint: https://raw.githubusercontent.com/ionos-cloud/ui-extensions-ionoscloud/gh-pages/extensions/ionoscloud/0.1.1 + noCache: {{ .Values.plugin.noCache }} +{{- end }} diff --git a/charts/ionoscloud/0.1.1/values.yaml b/charts/ionoscloud/0.1.1/values.yaml new file mode 100644 index 0000000..13e8787 --- /dev/null +++ b/charts/ionoscloud/0.1.1/values.yaml @@ -0,0 +1,30 @@ +global: + cattle: + systemDefaultRegistry: "" + kubectl: + repository: rancher/kubectl + tag: v1.20.2 + pullPolicy: IfNotPresent + imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" +pluginServer: + image: + repository: /ui-extension-ionoscloud + pullPolicy: Always + tag: 0.1.1 + service: + type: ClusterIP + port: 80 + targetPort: 8080 + deployment: + replicas: 1 + resources: {} + securityContext: {} + nodeSelector: {} + tolerations: [] + affinity: {} +plugin: + enabled: true + versionOverride: "" + noCache: false diff --git a/extensions/ionoscloud/0.1.1/files.txt b/extensions/ionoscloud/0.1.1/files.txt new file mode 100644 index 0000000..7158af9 --- /dev/null +++ b/extensions/ionoscloud/0.1.1/files.txt @@ -0,0 +1,13 @@ +plugin/ionoscloud-0.1.1.umd.min.5.js +plugin/ionoscloud-0.1.1.umd.min.5.js.map +plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js +plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js.map +plugin/ionoscloud-0.1.1.umd.min.js +plugin/ionoscloud-0.1.1.umd.min.js.map +plugin/ionoscloud-0.1.1.umd.min.machine-config.js +plugin/ionoscloud-0.1.1.umd.min.machine-config.js.map +plugin/ionoscloud-0.1.1.umd.min.vendors~cloud-credential~machine-config.js +plugin/ionoscloud-0.1.1.umd.min.vendors~cloud-credential~machine-config.js.map +plugin/ionoscloud-0.1.1.umd.min.vendors~machine-config.js +plugin/ionoscloud-0.1.1.umd.min.vendors~machine-config.js.map +plugin/package.json diff --git a/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.5.js b/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.5.js new file mode 100644 index 0000000..45ad24f --- /dev/null +++ b/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.5.js @@ -0,0 +1,2 @@ +(("undefined"!==typeof self?self:this)["webpackJsonpionoscloud_0_1_1"]=("undefined"!==typeof self?self:this)["webpackJsonpionoscloud_0_1_1"]||[]).push([[5],{"1bb6":function(e,o){const n=[{driver:{ionoscloud:{auth:{fields:{password:"Password",username:"Username",token:"Token",endpoint:"Endpoint"},placeholders:{password:"($IONOSCLOUD_PASSWORD)",username:"($IONOSCLOUD_USERNAME)",token:"($IONOSCLOUD_TOKEN)",endpoint:"($IONOSCLOUD_ENDPOINT)"}}}}}];e.exports=n.length<=1?n[0]:n}}]); +//# sourceMappingURL=ionoscloud-0.1.1.umd.min.5.js.map \ No newline at end of file diff --git a/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.5.js.map b/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.5.js.map new file mode 100644 index 0000000..56db442 --- /dev/null +++ b/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.5.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack://ionoscloud-0.1.1/./l10n/en-us.yaml"],"names":["doc","module","exports","length"],"mappings":"kLAAA,MAAMA,EAAM,CAAC,CAAE,OAAS,CAAE,WAAa,CAAE,KAAO,CAAE,OAAS,CAAE,SAAW,WAAY,SAAW,WAAY,MAAQ,QAAS,SAAW,YAAc,aAAe,CAAE,SAAW,yBAA0B,SAAW,yBAA0B,MAAQ,sBAAuB,SAAW,+BAC1RC,EAAOC,QAAUF,EAAIG,QAAU,EAAIH,EAAI,GAAKA","file":"ionoscloud-0.1.1.umd.min.5.js","sourcesContent":["const doc = [({\"driver\":({\"ionoscloud\":({\"auth\":({\"fields\":({\"password\":\"Password\", \"username\":\"Username\", \"token\":\"Token\", \"endpoint\":\"Endpoint\"}), \"placeholders\":({\"password\":\"($IONOSCLOUD_PASSWORD)\", \"username\":\"($IONOSCLOUD_USERNAME)\", \"token\":\"($IONOSCLOUD_TOKEN)\", \"endpoint\":\"($IONOSCLOUD_ENDPOINT)\"})})})})})];\nmodule.exports = doc.length <= 1 ? doc[0] : doc;"],"sourceRoot":""} \ No newline at end of file diff --git a/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js b/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js new file mode 100644 index 0000000..f6cda30 --- /dev/null +++ b/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js @@ -0,0 +1,2 @@ +(("undefined"!==typeof self?self:this)["webpackJsonpionoscloud_0_1_1"]=("undefined"!==typeof self?self:this)["webpackJsonpionoscloud_0_1_1"]||[]).push([[1],{c4ea:function(e,t,a){"use strict";a("cd46")},cd46:function(e,t,a){var o=a("f5b4");o.__esModule&&(o=o.default),"string"===typeof o&&(o=[[e.i,o,""]]),o.locals&&(e.exports=o.locals);var s=a("0ed3").default;s("b8c5a4fe",o,!0,{sourceMap:!1,shadowMode:!1})},f5b4:function(e,t,a){var o=a("5eaa");t=o(!1),t.push([e.i,'.clearfix[data-v-249f9195]:after,.clearfix[data-v-249f9195]:before{content:" ";display:table}.clearfix[data-v-249f9195]:after{clear:both}.list-unstyled[data-v-249f9195]{margin:0;padding:0;list-style-type:none}.no-select[data-v-249f9195]{-webkit-user-select:none;-moz-user-select:none;user-select:none}.no-resize[data-v-249f9195]{resize:none}.hand[data-v-249f9195]{cursor:pointer;cursor:hand}.fixed[data-v-249f9195]{table-layout:fixed}.clip[data-v-249f9195]{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.clip[data-v-249f9195],.force-wrap[data-v-249f9195]{word-wrap:break-word}.force-wrap[data-v-249f9195]{white-space:normal}.bordered-section[data-v-249f9195]{border-bottom:1px solid var(--border);margin-bottom:20px;padding-bottom:20px}.section-divider[data-v-249f9195]{margin-bottom:20px;margin-top:20px}.icon-spacer[data-v-249f9195]{width:24px}',""]),e.exports=t},ff98:function(e,t,a){"use strict";a.r(t);var o=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",[a("div",{staticClass:"row"},[a("div",{staticClass:"col span-6"},[a("LabeledInput",{staticClass:"mt-20",attrs:{value:e.value.decodedData.username,"label-key":"driver.ionoscloud.auth.fields.username","placeholder-key":"driver.ionoscloud.auth.placeholders.username",type:"text",mode:e.mode},on:{input:function(t){return e.value.setData("username",t)}}})],1),a("div",{staticClass:"col span-6"},[a("LabeledInput",{staticClass:"mt-20",attrs:{value:e.value.decodedData.password,"label-key":"driver.ionoscloud.auth.fields.password","placeholder-key":"driver.ionoscloud.auth.placeholders.password",type:"password",mode:e.mode},on:{input:function(t){return e.value.setData("password",t)}}})],1)]),a("div",{staticClass:"row"},[a("div",{staticClass:"col span-12"},[a("LabeledInput",{staticClass:"mt-20",attrs:{value:e.value.decodedData.token,"label-key":"driver.ionoscloud.auth.fields.token","placeholder-key":"driver.ionoscloud.auth.placeholders.token",type:"text",mode:e.mode},on:{input:function(t){return e.value.setData("token",t)}}})],1)]),a("div",{staticClass:"row"},[a("div",{staticClass:"col span-12"},[a("LabeledInput",{staticClass:"mt-20",attrs:{value:e.value.decodedData.endpoint||"https://api.ionos.com/cloudapi/v6","label-key":"driver.ionoscloud.auth.fields.endpoint","placeholder-key":"driver.ionoscloud.auth.placeholders.endpoint",type:"text",mode:e.mode},on:{input:function(t){return e.value.setData("endpoint",t)}}})],1)])])},s=[],d=a("eb32"),n=a("8e93"),i=a("466b"),l=a("da25"),r=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("button",{ref:"btn",staticClass:"btn role-primary",attrs:{disabled:e.disabled,"tab-index":e.tabIndex,"data-testid":e.componentTestid+"-async-button"},on:{click:e.clicked}},[e.busy?a("i",{staticClass:"icon icon-lg icon-spinner icon-spin"}):a("span",{staticClass:"icon-spacer"}),a("span",[e._v(e._s(e.displayLabel))]),a("span",{staticClass:"icon-spacer"})])},u=[],c=a("8bbf"),p=a.n(c),v=p.a.extend({props:{label:{type:String,default:void 0},labelKey:{type:String,default:void 0},disabled:{type:Boolean,default:!1},tabIndex:{type:Number,default:null},componentTestid:{type:String,default:"busy-button"},manual:{type:Boolean,default:!1}},data(){return{busy:!1}},computed:{displayLabel(){return this.label}},methods:{clicked(e){if(e&&(e.stopPropagation(),e.preventDefault()),this.disabled)return;const t=()=>{this.busy=!1};this.$set(this,"busy",!0),this.$emit("click",t)},focus(){this.$refs.btn.focus()}}}),h=v,f=(a("c4ea"),a("d802")),b=Object(f["a"])(h,r,u,!1,null,"249f9195",null),m=b.exports,y={components:{Banner:d["a"],BusyButton:m,LabeledInput:n["a"],LabeledSelect:i["a"]},props:{mode:{type:String,required:!0},value:{type:Object,required:!0}},async fetch(){this.driver=await this.$store.dispatch("rancher/find",{type:"nodedriver",id:"ionoscloud"})},data(){return this.mode!==l["a"]&&(this.value.decodedData.username=this.value.annotations["ionoscloud.cattle.io/username"],this.value.decodedData.password=this.value.annotations["ionoscloud.cattle.io/password"],this.value.decodedData.token=this.value.annotations["ionoscloud.cattle.io/token"],this.value.decodedData.endpoint=this.value.annotations["ionoscloud.cattle.io/endpoint"]||"https://api.ionos.com/cloudapi/v6"),{busy:!1,driver:{},allowBusy:!1,error:""}},computed:{canAuthenticate(){var e,t,a,o,s,d;return!(null===(e=this.value)||void 0===e||null===(t=e.decodedData)||void 0===t||!t.token)||!(null===(a=this.value)||void 0===a||null===(o=a.decodedData)||void 0===o||!o.username)&&!(null===(s=this.value)||void 0===s||null===(d=s.decodedData)||void 0===d||!d.password)}},created(){this.$emit("validationChanged",!1)},methods:{test(){return this.value.annotations["ionoscloud.cattle.io/username"]=this.value.decodedData.username,this.value.annotations["ionoscloud.cattle.io/password"]=this.value.decodedData.password,this.value.annotations["ionoscloud.cattle.io/token"]=this.value.decodedData.token,this.value.annotations["ionoscloud.cattle.io/endpoint"]=this.value.decodedData.endpoint,this.value.username=this.value.decodedData.username,this.value.password=this.value.decodedData.password,this.value.token=this.value.decodedData.token,this.value.endpoint=this.value.decodedData.endpoint,!0},clear(){this.$emit("validationChanged",!1)}}},w=y,k=Object(f["a"])(w,o,s,!1,null,null,null);t["default"]=k.exports}}]); +//# sourceMappingURL=ionoscloud-0.1.1.umd.min.cloud-credential.js.map \ No newline at end of file diff --git a/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js.map b/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js.map new file mode 100644 index 0000000..b644a31 --- /dev/null +++ b/extensions/ionoscloud/0.1.1/plugin/ionoscloud-0.1.1.umd.min.cloud-credential.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack://ionoscloud-0.1.1/./components/BusyButton.vue?b4ed","webpack://ionoscloud-0.1.1/./components/BusyButton.vue?5553","webpack://ionoscloud-0.1.1/./components/BusyButton.vue?f0f9","webpack://ionoscloud-0.1.1/./cloud-credential/ionoscloud.vue?fb9e","webpack://ionoscloud-0.1.1/./components/BusyButton.vue?5dd2","webpack://ionoscloud-0.1.1/./components/BusyButton.vue?7318","webpack://ionoscloud-0.1.1/./components/BusyButton.vue?bdd1","webpack://ionoscloud-0.1.1/./components/BusyButton.vue","webpack://ionoscloud-0.1.1/cloud-credential/ionoscloud.vue","webpack://ionoscloud-0.1.1/./cloud-credential/ionoscloud.vue?3ee9","webpack://ionoscloud-0.1.1/./cloud-credential/ionoscloud.vue"],"names":["content","__esModule","default","module","i","locals","exports","add","___CSS_LOADER_API_IMPORT___","push","render","_vm","this","_h","$createElement","_c","_self","staticClass","attrs","value","decodedData","username","mode","on","$event","setData","password","token","endpoint","staticRenderFns","ref","disabled","tabIndex","componentTestid","clicked","_v","_s","displayLabel","Vue","extend","props","label","type","String","undefined","labelKey","Boolean","Number","manual","data","busy","computed","methods","stopPropagation","preventDefault","cb","$set","$emit","focus","$refs","btn","component","components","Banner","BusyButton","LabeledInput","LabeledSelect","required","id","driver","allowBusy","error","canAuthenticate","created","test","clear"],"mappings":"+LAAA,W,qBCGA,IAAIA,EAAU,EAAQ,QACnBA,EAAQC,aAAYD,EAAUA,EAAQE,SACnB,kBAAZF,IAAsBA,EAAU,CAAC,CAACG,EAAOC,EAAIJ,EAAS,MAC7DA,EAAQK,SAAQF,EAAOG,QAAUN,EAAQK,QAE5C,IAAIE,EAAM,EAAQ,QAAkEL,QACvEK,EAAI,WAAYP,GAAS,EAAM,CAAC,WAAY,EAAM,YAAa,K,qBCR5E,IAAIQ,EAA8B,EAAQ,QAC1CF,EAAUE,GAA4B,GAEtCF,EAAQG,KAAK,CAACN,EAAOC,EAAI,61BAAg2B,KAEz3BD,EAAOG,QAAUA,G,yCCNjB,IAAII,EAAS,WAAa,IAAIC,EAAIC,KAASC,EAAGF,EAAIG,eAAmBC,EAAGJ,EAAIK,MAAMD,IAAIF,EAAG,OAAOE,EAAG,MAAM,CAACA,EAAG,MAAM,CAACE,YAAY,OAAO,CAACF,EAAG,MAAM,CAACE,YAAY,cAAc,CAACF,EAAG,eAAe,CAACE,YAAY,QAAQC,MAAM,CAAC,MAAQP,EAAIQ,MAAMC,YAAYC,SAAS,YAAY,yCAAyC,kBAAkB,+CAA+C,KAAO,OAAO,KAAOV,EAAIW,MAAMC,GAAG,CAAC,MAAQ,SAASC,GAAQ,OAAOb,EAAIQ,MAAMM,QAAQ,WAAYD,QAAc,GAAGT,EAAG,MAAM,CAACE,YAAY,cAAc,CAACF,EAAG,eAAe,CAACE,YAAY,QAAQC,MAAM,CAAC,MAAQP,EAAIQ,MAAMC,YAAYM,SAAS,YAAY,yCAAyC,kBAAkB,+CAA+C,KAAO,WAAW,KAAOf,EAAIW,MAAMC,GAAG,CAAC,MAAQ,SAASC,GAAQ,OAAOb,EAAIQ,MAAMM,QAAQ,WAAYD,QAAc,KAAKT,EAAG,MAAM,CAACE,YAAY,OAAO,CAACF,EAAG,MAAM,CAACE,YAAY,eAAe,CAACF,EAAG,eAAe,CAACE,YAAY,QAAQC,MAAM,CAAC,MAAQP,EAAIQ,MAAMC,YAAYO,MAAM,YAAY,sCAAsC,kBAAkB,4CAA4C,KAAO,OAAO,KAAOhB,EAAIW,MAAMC,GAAG,CAAC,MAAQ,SAASC,GAAQ,OAAOb,EAAIQ,MAAMM,QAAQ,QAASD,QAAc,KAAKT,EAAG,MAAM,CAACE,YAAY,OAAO,CAACF,EAAG,MAAM,CAACE,YAAY,eAAe,CAACF,EAAG,eAAe,CAACE,YAAY,QAAQC,MAAM,CAAC,MAAQP,EAAIQ,MAAMC,YAAYQ,UAAY,oCAAoC,YAAY,yCAAyC,kBAAkB,+CAA+C,KAAO,OAAO,KAAOjB,EAAIW,MAAMC,GAAG,CAAC,MAAQ,SAASC,GAAQ,OAAOb,EAAIQ,MAAMM,QAAQ,WAAYD,QAAc,QAC1mDK,EAAkB,G,gDCDlB,EAAS,WAAa,IAAIlB,EAAIC,KAASC,EAAGF,EAAIG,eAAmBC,EAAGJ,EAAIK,MAAMD,IAAIF,EAAG,OAAOE,EAAG,SAAS,CAACe,IAAI,MAAMb,YAAY,mBAAmBC,MAAM,CAAC,SAAWP,EAAIoB,SAAS,YAAYpB,EAAIqB,SAAS,cAAcrB,EAAIsB,gBAAkB,iBAAiBV,GAAG,CAAC,MAAQZ,EAAIuB,UAAU,CAAEvB,EAAQ,KAAEI,EAAG,IAAI,CAACE,YAAY,wCAAwCF,EAAG,OAAO,CAACE,YAAY,gBAAgBF,EAAG,OAAO,CAACJ,EAAIwB,GAAGxB,EAAIyB,GAAGzB,EAAI0B,iBAAiBtB,EAAG,OAAO,CAACE,YAAY,mBAC7c,EAAkB,G,qBCIPqB,MAAIC,OAAO,CACxBC,MAAO,CAILC,MAAO,CACLC,KAASC,OACTzC,aAAS0C,GAEXC,SAAU,CACRH,KAASC,OACTzC,aAAS0C,GAEXb,SAAU,CACRW,KAASI,QACT5C,SAAS,GAEX8B,SAAU,CACRU,KAASK,OACT7C,QAAS,MAOX+B,gBAAiB,CACfS,KAASC,OACTzC,QAAS,eAGX8C,OAAQ,CACNN,KAASI,QACT5C,SAAS,IAIb+C,OACE,MAAO,CAAEC,MAAM,IAGjBC,SAAU,CACRd,eAEE,OAAOzB,KAAK6B,QAIhBW,QAAS,CACPlB,QAAQV,GAMN,GALIA,IACFA,EAAO6B,kBACP7B,EAAO8B,kBAGJ1C,KAAKmB,SACR,OAGF,MAAMwB,EAA0B,KAC9B3C,KAAKsC,MAAO,GAGdtC,KAAK4C,KAAK5C,KAAM,QAAQ,GAExBA,KAAK6C,MAAM,QAASF,IAGtBG,QACG9C,KAAK+C,MAAMC,IAAoBF,YC1E+Y,I,wBCQjbG,EAAY,eACd,EACA,EACA,GACA,EACA,KACA,WACA,MAIa,EAAAA,E,QCZA,GACfC,YACAC,cACAC,aACAC,oBACAC,sBAGA1B,OACAlB,MACAoB,YACAyB,aAGAhD,OACAuB,YACAyB,cAIA,cACA,uDACAzB,kBACA0B,mBAIAnB,OAQA,OAPA,qBACA,wFACA,wFACA,kFACA,8HAGA,CACAC,QACAmB,UACAC,aACAC,WAIApB,UAEAqB,kBAAA,gBACA,8FACA,yFACA,wFAIAC,UACA,oCAGArB,SACAsB,OAUA,OATA,wFACA,wFACA,kFACA,wFAEA,oDACA,oDACA,8CACA,qDACA,GAGAC,QAEA,sCC/EiY,ICO7X,EAAY,eACd,EACAjE,EACAmB,GACA,EACA,KACA,KACA,MAIa,e","file":"ionoscloud-0.1.1.umd.min.cloud-credential.js","sourcesContent":["export * from \"-!../../../node_modules/vue-style-loader/index.js??ref--10-oneOf-1-0!../../../node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??ref--10-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--10-oneOf-1-2!../../../node_modules/postcss-loader/src/index.js??ref--10-oneOf-1-3!../../../node_modules/sass-loader/dist/cjs.js??ref--10-oneOf-1-4!../../../node_modules/cache-loader/dist/cjs.js??ref--2-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader/lib/index.js??vue-loader-options!./BusyButton.vue?vue&type=style&index=0&id=249f9195&prod&lang=scss&scoped=true&\"","// style-loader: Adds some css to the DOM by adding a \n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--14-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--2-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader/lib/index.js??vue-loader-options!./ionoscloud.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--14-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--2-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader/lib/index.js??vue-loader-options!./ionoscloud.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./ionoscloud.vue?vue&type=template&id=7ffa3e75&scoped=true&\"\nimport script from \"./ionoscloud.vue?vue&type=script&lang=js&\"\nexport * from \"./ionoscloud.vue?vue&type=script&lang=js&\"\nimport style0 from \"./ionoscloud.vue?vue&type=style&index=0&id=7ffa3e75&prod&scoped=true&lang=scss&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/@vue/cli-service/node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"7ffa3e75\",\n null\n \n)\n\nexport default component.exports","export * from \"-!../../../node_modules/vue-style-loader/index.js??ref--10-oneOf-1-0!../../../node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??ref--10-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--10-oneOf-1-2!../../../node_modules/postcss-loader/src/index.js??ref--10-oneOf-1-3!../../../node_modules/sass-loader/dist/cjs.js??ref--10-oneOf-1-4!../../../node_modules/cache-loader/dist/cjs.js??ref--2-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader/lib/index.js??vue-loader-options!./ionoscloud.vue?vue&type=style&index=0&id=7ffa3e75&prod&scoped=true&lang=scss&\"","// style-loader: Adds some css to the DOM by adding a \n","import mod from \"-!../../../../cache-loader/dist/cjs.js??ref--14-0!../../../../thread-loader/dist/cjs.js!../../../../babel-loader/lib/index.js!../../../../cache-loader/dist/cjs.js??ref--2-0!../../../../@vue/cli-service/node_modules/vue-loader/lib/index.js??vue-loader-options!./LabeledSelect.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../cache-loader/dist/cjs.js??ref--14-0!../../../../thread-loader/dist/cjs.js!../../../../babel-loader/lib/index.js!../../../../cache-loader/dist/cjs.js??ref--2-0!../../../../@vue/cli-service/node_modules/vue-loader/lib/index.js??vue-loader-options!./LabeledSelect.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./LabeledSelect.vue?vue&type=template&id=73934cd1&scoped=true&\"\nimport script from \"./LabeledSelect.vue?vue&type=script&lang=js&\"\nexport * from \"./LabeledSelect.vue?vue&type=script&lang=js&\"\nimport style0 from \"./LabeledSelect.vue?vue&type=style&index=0&id=73934cd1&prod&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../@vue/cli-service/node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"73934cd1\",\n null\n \n)\n\nexport default component.exports","var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","var Symbol = require('./_Symbol'),\n Uint8Array = require('./_Uint8Array'),\n eq = require('./eq'),\n equalArrays = require('./_equalArrays'),\n mapToArray = require('./_mapToArray'),\n setToArray = require('./_setToArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nmodule.exports = equalByTag;\n","/**\n * Sets the width of a DOM element. Adapted from [youmightnotneedjquery.com](https://youmightnotneedjquery.com/#set_width)\n * @param {Element} el - The target DOM element\n * @param {function | string | number} val - The desired width represented as a Number\n */\nexport function setWidth(el, val) {\n if (!el) {\n return;\n }\n\n if (typeof val === 'function') {\n val = val();\n }\n\n if (typeof val === 'string') {\n el.style.width = val;\n\n return;\n }\n\n el.style.width = `${ val }px`;\n}\n\n/**\n * Gets the width of a DOM element. Adapted from [youmightnotneedjquery.com](https://youmightnotneedjquery.com/#get_width)\n * @param {Element} el - The target DOM element\n * @returns Number representing the width for the provided element\n */\nexport function getWidth(el) {\n if (!el || !el.length) {\n return;\n }\n\n if (el.length) {\n return parseFloat(getComputedStyle(el[0]).width.replace('px', ''));\n } else {\n return parseFloat(getComputedStyle(el).width.replace('px', ''));\n }\n}\n","import Vue from 'vue';\nimport { _EDIT, _VIEW } from '@shell/config/query-params';\nimport { getWidth, setWidth } from '@shell/utils/width';\n\ninterface LabeledFormElement {\n raised: boolean;\n focused: boolean;\n blurred: number | null;\n}\n\nexport default Vue.extend({\n inheritAttrs: false,\n\n props: {\n mode: {\n type: String,\n default: _EDIT,\n },\n\n label: {\n type: String,\n default: null\n },\n\n labelKey: {\n type: String,\n default: null\n },\n\n placeholderKey: {\n type: String,\n default: null\n },\n\n tooltip: {\n type: [String, Object],\n default: null\n },\n\n hoverTooltip: {\n type: Boolean,\n default: true,\n },\n\n tooltipKey: {\n type: String,\n default: null\n },\n\n required: {\n type: Boolean,\n default: false,\n },\n\n disabled: {\n type: Boolean,\n default: false,\n },\n\n placeholder: {\n type: [String, Number],\n default: ''\n },\n\n value: {\n type: [String, Number, Object],\n default: ''\n },\n\n options: {\n default: null,\n type: Array\n },\n\n searchable: {\n default: false,\n type: Boolean\n },\n\n rules: {\n default: () => [],\n type: Array,\n // we only want functions in the rules array\n validator: (rules: any) => rules.every((rule: any) => ['function'].includes(typeof rule))\n }\n },\n\n data(): LabeledFormElement {\n return {\n raised: this.mode === _VIEW || !!`${ this.value }`,\n focused: false,\n blurred: null,\n };\n },\n\n computed: {\n requiredField(): boolean {\n // using \"any\" for a type on \"rule\" here is dirty but the use of the optional chaining operator makes it safe for what we're doing here.\n return (this.required || this.rules.some((rule: any): boolean => rule?.name === 'required'));\n },\n empty(): boolean {\n return !!`${ this.value }`;\n },\n\n isView(): boolean {\n return this.mode === _VIEW;\n },\n\n isDisabled(): boolean {\n return this.disabled || this.isView;\n },\n\n isSearchable(): boolean {\n const { searchable } = this;\n const options = ( this.options || [] );\n\n if (searchable || options.length >= 10) {\n return true;\n }\n\n return false;\n },\n validationMessage(): string | undefined {\n // we want to grab the required rule passed in if we can but if it's not there then we can just grab it from the formRulesGenerator\n const requiredRule = this.rules.find((rule: any) => rule?.name === 'required');\n const ruleMessages = [];\n const value = this?.value;\n\n if (requiredRule && this.blurred && !this.focused) {\n const message = requiredRule(value);\n\n if (!!message) {\n return message;\n }\n }\n\n for (const rule of this.rules) {\n const message = rule(value);\n\n if (!!message && rule.name !== 'required') { // we're catching 'required' above so we can ignore it here\n ruleMessages.push(message);\n }\n }\n if (ruleMessages.length > 0 && (this.blurred || this.focused)) {\n return ruleMessages.join(', ');\n } else {\n return undefined;\n }\n }\n },\n\n methods: {\n resizeHandler() {\n // since the DD is positioned there is no way to 'inherit' the size of the input, this calcs the size of the parent and set the dd width if it is smaller. If not let it grow with the regular styles\n this.$nextTick(() => {\n const DD = (this.$refs.select as HTMLElement).querySelector('ul.vs__dropdown-menu');\n\n const selectWidth = getWidth(this.$refs.select as Element) || 0;\n const dropWidth = getWidth(DD as Element) || 0;\n\n if (dropWidth < selectWidth) {\n setWidth(DD as Element, selectWidth);\n }\n });\n },\n onFocus() {\n this.$emit('on-focus');\n\n return this.onFocusLabeled();\n },\n\n onFocusLabeled() {\n this.raised = true;\n this.focused = true;\n },\n\n onBlur() {\n this.$emit('on-blur');\n\n return this.onBlurLabeled();\n },\n\n onBlurLabeled() {\n this.focused = false;\n\n if ( !this.value ) {\n this.raised = false;\n }\n\n this.blurred = Date.now();\n }\n }\n});\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nmodule.exports = baseUnary;\n","// style-loader: Adds some css to the DOM by adding a \n","import mod from \"-!../../../cache-loader/dist/cjs.js??ref--14-0!../../../thread-loader/dist/cjs.js!../../../babel-loader/lib/index.js!../../../cache-loader/dist/cjs.js??ref--2-0!../../../@vue/cli-service/node_modules/vue-loader/lib/index.js??vue-loader-options!./Loading.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../cache-loader/dist/cjs.js??ref--14-0!../../../thread-loader/dist/cjs.js!../../../babel-loader/lib/index.js!../../../cache-loader/dist/cjs.js??ref--2-0!../../../@vue/cli-service/node_modules/vue-loader/lib/index.js??vue-loader-options!./Loading.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./Loading.vue?vue&type=template&id=e765d1f4&scoped=true&\"\nimport script from \"./Loading.vue?vue&type=script&lang=js&\"\nexport * from \"./Loading.vue?vue&type=script&lang=js&\"\nimport style0 from \"./Loading.vue?vue&type=style&index=0&id=e765d1f4&prod&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../@vue/cli-service/node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"e765d1f4\",\n null\n \n)\n\nexport default component.exports","// Imports\nvar ___CSS_LOADER_API_IMPORT___ = require(\"../../../../@vue/cli-service/node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.id, \".clearfix[data-v-daca0776]:after,.clearfix[data-v-daca0776]:before{content:\\\" \\\";display:table}.clearfix[data-v-daca0776]:after{clear:both}.list-unstyled[data-v-daca0776]{margin:0;padding:0;list-style-type:none}.no-select[data-v-daca0776]{-webkit-user-select:none;-moz-user-select:none;user-select:none}.no-resize[data-v-daca0776]{resize:none}.hand[data-v-daca0776]{cursor:pointer;cursor:hand}.fixed[data-v-daca0776]{table-layout:fixed}.clip[data-v-daca0776]{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.clip[data-v-daca0776],.force-wrap[data-v-daca0776]{word-wrap:break-word}.force-wrap[data-v-daca0776]{white-space:normal}.bordered-section[data-v-daca0776]{border-bottom:1px solid var(--border);margin-bottom:20px;padding-bottom:20px}.section-divider[data-v-daca0776]{margin-bottom:20px;margin-top:20px}.string-list[data-v-daca0776]{display:flex;flex-direction:column;width:auto}.string-list.readonly[data-v-daca0776]{cursor:default;opacity:.4}.string-list .string-list-box[data-v-daca0776]{min-height:200px;height:100%;outline:none;overflow-y:auto;overflow-x:hidden;border:solid var(--border-width) var(--input-border);padding-top:3px}.string-list .string-list-box .static[data-v-daca0776]{height:25px;padding:3px}.string-list .string-list-box .item[data-v-daca0776]{outline:none}.string-list .string-list-box .item.selected[data-v-daca0776]{background:var(--primary);color:var(--primary-hover-text)}.string-list .string-list-box .item.readonly[data-v-daca0776]{pointer-events:none}.string-list .string-list-box .item .label[data-v-daca0776]{display:block;width:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;padding-top:1px}.string-list .string-list-box .create-field[data-v-daca0776]{padding-top:1px;margin-bottom:7px}.string-list .string-list-box .labeled-input[data-v-daca0776]{padding-top:0;padding-bottom:0;border-radius:0}.string-list .string-list-box .labeled-input.error[data-v-daca0776]{border:none;box-shadow:0 0 0 var(--outline-width) var(--error)}.string-list .string-list-footer[data-v-daca0776]{--footer-height:28px;height:var(--footer-height);margin-top:5px;display:flex;justify-content:space-between;gap:.5rem}.string-list .string-list-footer.left[data-v-daca0776]{flex-direction:row}.string-list .string-list-footer.right[data-v-daca0776]{flex-direction:row-reverse}.string-list .string-list-footer .action-buttons[data-v-daca0776]{display:flex;flex-direction:row-reverse;gap:.5rem}.string-list .string-list-footer .action-buttons .btn[data-v-daca0776]{min-height:var(--footer-height);line-height:0;border-radius:2px}.string-list .string-list-footer .action-buttons .btn[data-v-daca0776]:disabled{cursor:default;pointer-events:none}.string-list .string-list-footer .messages[data-v-daca0776]{line-height:var(--footer-height)}.string-list .string-list-footer .messages .error[data-v-daca0776],.string-list .string-list-footer .messages .icon-warning[data-v-daca0776]{color:var(--error);line-height:inherit}[data-v-daca0776] .labeled-input INPUT.no-label,[data-v-daca0776] .labeled-input INPUT:focus.no-label,[data-v-daca0776] .labeled-input INPUT:hover.no-label{padding:1px 0 0 0}[data-v-daca0776] .labeled-input.compact-input{min-height:0}\", \"\"]);\n// Exports\nmodule.exports = exports;\n","// Imports\nvar ___CSS_LOADER_API_IMPORT___ = require(\"../../../../../@vue/cli-service/node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.id, \".clearfix:after,.clearfix:before{content:\\\" \\\";display:table}.clearfix:after{clear:both}.list-unstyled{margin:0;padding:0;list-style-type:none}.no-select{-webkit-user-select:none;-moz-user-select:none;user-select:none}.no-resize{resize:none}.hand{cursor:pointer;cursor:hand}.fixed{table-layout:fixed}.clip{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.clip,.force-wrap{word-wrap:break-word}.force-wrap{white-space:normal}.bordered-section{border-bottom:1px solid var(--border);margin-bottom:20px;padding-bottom:20px}.section-divider{margin-bottom:20px;margin-top:20px}.checkbox-outer-container{display:inline-flex;flex-direction:column}.checkbox-outer-container-description{color:var(--input-label);font-size:14px;margin-left:19px;margin-top:5px;opacity:.8}.checkbox-container{position:relative;display:inline-flex;align-items:center;margin:0;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:var(--border-radius)}.checkbox-container .checkbox-label{color:var(--input-label);display:inline-flex;margin:0 10px 0 5px}.checkbox-container .checkbox-label.checkbox-primary{color:inherit;font-weight:600}.checkbox-container .checkbox-info{line-height:normal;margin-left:2px}.checkbox-container .checkbox-custom{height:14px;width:14px;background-color:var(--body-bg);border-radius:var(--border-radius);transition:all .3s ease-out;border:1px solid var(--border)}.checkbox-container input{opacity:0;position:absolute;z-index:-1}.checkbox-container input:checked~.checkbox-custom{background-color:var(--primary);transform:rotate(0deg) scale(1);opacity:1;border:1px solid var(--primary)}.checkbox-container .checkbox-custom:after{position:absolute;content:\\\"\\\";left:0;top:0;height:0;width:0;border-radius:var(--border-radius);border:solid;border-color:var(--input-text);border-width:0 3px 3px 0;transform:rotate(0deg) scale(0);opacity:1}.checkbox-container input:checked~.checkbox-custom:after{transform:rotate(45deg) scale(1);opacity:1;left:4px;width:4px;height:10px;border:solid;border-color:var(--checkbox-tick);border-width:0 2px 2px 0;background-color:transparent}.checkbox-container input:checked~.checkbox-custom.indeterminate:after{transform:scale(1);opacity:1;left:3px;top:2px;width:6px;height:5px;border:solid;border-color:var(--checkbox-tick);border-width:0 0 2px 0;background-color:transparent}.checkbox-container.disabled .checkbox-custom,.checkbox-container.disabled input:checked~.checkbox-custom{background-color:var(--checkbox-disabled-bg);border-color:var(--checkbox-disabled-bg)}.checkbox-container.disabled input:checked~.checkbox-custom:after{border-color:var(--checkbox-tick-disabled)}.checkbox-container.disabled{cursor:not-allowed}.checkbox-container .checkbox-view{display:flex;flex-direction:column}.checkbox-container .checkbox-view LABEL{color:var(--input-label)}\", \"\"]);\n// Exports\nmodule.exports = exports;\n","import { get } from './object';\nimport { strPad } from './string';\n\n// Based on https://github.com/emberjs/ember.js/blob/master/packages/@ember/-internals/runtime/lib/type-of.js\n// and https://github.com/emberjs/ember.js/blob/master/packages/@ember/-internals/runtime/lib/mixins/array.js\n/*\nCopyright (c) 2019 Yehuda Katz, Tom Dale and Ember.js contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n// ........................................\n// TYPING & ARRAY MESSAGING\n//\nconst TYPE_MAP = {\n '[object Boolean]': 'boolean',\n '[object Number]': 'number',\n '[object String]': 'string',\n '[object Function]': 'function',\n '[object Array]': 'array',\n '[object Date]': 'date',\n '[object RegExp]': 'regexp',\n '[object Object]': 'object',\n '[object FileList]': 'filelist',\n};\n\nconst { toString } = Object.prototype;\n\n/**\n Returns a consistent type for the passed object.\n\n Use this instead of the built-in `typeof` to get the type of an item.\n It will return the same result across all browsers and includes a bit\n more detail. Here is what will be returned:\n\n | Return Value | Meaning |\n |---------------|------------------------------------------------------|\n | 'string' | String primitive or String object. |\n | 'number' | Number primitive or Number object. |\n | 'boolean' | Boolean primitive or Boolean object. |\n | 'null' | Null value |\n | 'undefined' | Undefined value |\n | 'function' | A function |\n | 'array' | An instance of Array |\n | 'regexp' | An instance of RegExp |\n | 'date' | An instance of Date |\n | 'filelist' | An instance of FileList |\n | 'error' | An instance of the Error object |\n | 'object' | A JavaScript object |\n\n Examples:\n\n import { typeOf } from '@shell/utils/type-of';\n\n typeOf(); // 'undefined'\n typeOf(null); // 'null'\n typeOf(undefined); // 'undefined'\n typeOf('michael'); // 'string'\n typeOf(new String('michael')); // 'string'\n typeOf(101); // 'number'\n typeOf(new Number(101)); // 'number'\n typeOf(true); // 'boolean'\n typeOf(new Boolean(true)); // 'boolean'\n typeOf(A); // 'function'\n typeOf([1, 2, 90]); // 'array'\n typeOf(/abc/); // 'regexp'\n typeOf(new Date()); // 'date'\n typeOf(event.target.files); // 'filelist'\n typeOf(new Error('teamocil')); // 'error'\n\n // 'normal' JavaScript object\n typeOf({ a: 'b' }); // 'object'\n*/\nexport function typeOf(item) {\n if (item === null) {\n return 'null';\n }\n if (item === undefined) {\n return 'undefined';\n }\n let ret = TYPE_MAP[toString.call(item)] || 'object';\n\n if (ret === 'object') {\n if (item instanceof Error) {\n ret = 'error';\n } else if (item instanceof Date) {\n ret = 'date';\n }\n }\n\n return ret;\n}\n\nexport function spaceship(a, b) {\n const diff = a - b;\n\n return (diff > 0) - (diff < 0);\n}\n\nconst TYPE_ORDER = {\n undefined: 0,\n null: 1,\n boolean: 2,\n number: 3,\n string: 4,\n array: 5,\n object: 6,\n instance: 7,\n function: 8,\n class: 9,\n date: 10,\n};\n\nexport function compare(a, b) {\n const typeA = typeOf(a);\n const typeB = typeOf(b);\n\n const res = spaceship(TYPE_ORDER[typeA], TYPE_ORDER[typeB]);\n\n if ( res ) {\n return res;\n }\n\n switch (typeA) {\n case 'boolean':\n case 'number':\n return spaceship(a, b);\n\n case 'string':\n return spaceship(a.localeCompare(b), 0);\n\n case 'array': {\n const aLen = a.length;\n const bLen = b.length;\n const len = Math.min(aLen, bLen);\n\n for (let i = 0; i < len; i++) {\n const r = compare(a[i], b[i]);\n\n if (r !== 0) {\n return r;\n }\n }\n\n // all elements are equal now\n // shorter array should be ordered first\n return spaceship(aLen, bLen);\n }\n case 'date':\n return spaceship(a.getTime(), b.getTime());\n }\n\n return 0;\n}\n\nexport function parseField(str) {\n const parts = str.split(/:/);\n\n if ( parts.length === 2 && parts[1] === 'desc' ) {\n return { field: parts[0], reverse: true };\n } else {\n return { field: str, reverse: false };\n }\n}\n\nexport function sortBy(ary, keys, desc) {\n if ( !Array.isArray(keys) ) {\n keys = [keys];\n }\n\n return ary.slice().sort((objA, objB) => {\n for ( let i = 0 ; i < keys.length ; i++ ) {\n const parsed = parseField(keys[i]);\n const a = get(objA, parsed.field);\n const b = get(objB, parsed.field);\n let res = compare(a, b);\n\n if ( res ) {\n if ( desc ) {\n res *= -1;\n }\n\n if ( parsed.reverse ) {\n res *= -1;\n }\n\n return res;\n }\n }\n\n return 0;\n });\n}\n\n// Turn foo1-bar2 into foo0000000001-bar0000000002 so that the numbers sort numerically\nconst splitRegex = /([^\\d]+)/;\nconst notNumericRegex = /^[0-9]+$/;\n\nexport function sortableNumericSuffix(str) {\n if ( typeof str !== 'string' ) {\n return str;\n }\n\n return str.split(splitRegex).map(x => x.match(notNumericRegex) ? strPad(x, 10, '0') : x).join('').trim();\n}\n\nexport function isNumeric(num) {\n return !!`${ num }`.match(notNumericRegex);\n}\n","import { findBy } from '@shell/utils/array';\nimport { sortBy } from '@shell/utils/sort';\n\nlet NEXT_ID = 1;\n\nexport const BEFORE_SAVE_HOOKS = '_beforeSaveHooks';\nexport const AFTER_SAVE_HOOKS = '_afterSaveHooks';\n\nexport default {\n methods: {\n registerBeforeHook(boundFn, name, priority = 99, boundFnContext) {\n this._registerHook(BEFORE_SAVE_HOOKS, boundFn, name, priority, boundFnContext);\n },\n\n unregisterBeforeSaveHook(name) {\n this[BEFORE_SAVE_HOOKS] = this[BEFORE_SAVE_HOOKS].filter((hook) => {\n // BEFORE_SAVE_HOOKS is an array of objects with keys\n // fn, name and priority.\n return hook.name !== name;\n });\n },\n\n registerAfterHook(boundFn, name, priority) {\n this._registerHook(AFTER_SAVE_HOOKS, boundFn, name, priority);\n },\n\n async applyHooks(key, ...args) {\n if ( !key ) {\n throw new Error('Must specify key');\n }\n\n const hooks = sortBy(this[key] || [], ['priority', 'name']);\n const out = {};\n\n for ( const x of hooks ) {\n console.debug('Applying hook', x.name); // eslint-disable-line no-console\n out[x.name] = await x.fn.apply(x.fnContext || this, args);\n }\n\n return out;\n },\n\n _registerHook(key, fn, name, priority, fnContext) {\n if ( !key ) {\n throw new Error('Must specify key');\n }\n\n if ( !name ) {\n name = `hook_${ NEXT_ID }`;\n NEXT_ID++;\n }\n\n if ( !priority ) {\n priority = 99;\n }\n\n let hooks = this[key];\n\n if ( !hooks ) {\n hooks = [];\n this[key] = hooks;\n }\n\n let entry = findBy(hooks, 'name', name);\n\n if ( entry ) {\n entry.priority = priority;\n entry.fn = fn;\n entry.fnContext = fnContext;\n } else {\n entry = {\n name,\n priority,\n fn,\n fnContext\n };\n\n hooks.push(entry);\n }\n },\n },\n};\n","import { SCHEMA } from '@shell/config/types';\n\nimport { applyChangeset, changeset, changesetConflicts } from '@shell/utils/object';\n\nexport const KEY_FIELD_FOR = {\n [SCHEMA]: '_id',\n default: 'id',\n};\n\nexport function keyFieldFor(type) {\n return KEY_FIELD_FOR[type] || KEY_FIELD_FOR['default'];\n}\n\nexport function normalizeType(type) {\n type = (type?.type || type || '').toLowerCase();\n\n return type;\n}\n\n// Detect and resolve conflicts from a 409 response.\n// If they are resolved, return a false-y value\n// Else they can't be resolved, return an array of errors to show to the user.\nexport function handleConflict(initialValueJSON, value, liveValue, rootGetters, store) {\n const orig = store.dispatch(`cleanForDiff`, initialValueJSON);\n const user = store.dispatch(`cleanForDiff`, value.toJSON());\n const cur = store.dispatch(`cleanForDiff`, liveValue.toJSON());\n\n const bgChange = changeset(orig, cur);\n const userChange = changeset(orig, user);\n const actualConflicts = changesetConflicts(bgChange, userChange);\n\n console.log('Background Change', bgChange); // eslint-disable-line no-console\n console.log('User Change', userChange); // eslint-disable-line no-console\n console.log('Conflicts', actualConflicts); // eslint-disable-line no-console\n\n value.metadata.resourceVersion = liveValue.metadata.resourceVersion;\n applyChangeset(value, bgChange);\n\n if ( actualConflicts.length ) {\n // Stop the save and let the user inspect and continue editing\n const out = [rootGetters['i18n/t']('validation.conflict', { fields: actualConflicts.join(', '), fieldCount: actualConflicts.length })];\n\n return out;\n } else {\n // The save can continue\n return false;\n }\n}\n","import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';\nimport { LAST_NAMESPACE } from '@shell/store/prefs';\nimport { exceptionToErrorsArray } from '@shell/utils/error';\nimport ChildHook, { BEFORE_SAVE_HOOKS, AFTER_SAVE_HOOKS } from '@shell/mixins/child-hook';\nimport { clear } from '@shell/utils/array';\nimport { DEFAULT_WORKSPACE } from '@shell/config/types';\nimport { handleConflict } from '@shell/plugins/dashboard-store/normalize';\n\nexport default {\n\n name: 'CreateEditView',\n\n mixins: [ChildHook],\n\n data() {\n // Keep label and annotation filters in data so each resource CRUD page can alter individually\n return { errors: [] };\n },\n\n computed: {\n isCreate() {\n return this.mode === _CREATE;\n },\n\n isEdit() {\n return this.mode === _EDIT;\n },\n\n isView() {\n return this.mode === _VIEW;\n },\n\n schema() {\n const inStore = this.storeOverride || this.$store.getters['currentStore'](this.value.type);\n\n return this.$store.getters[`${ inStore }/schemaFor`](this.value.type);\n },\n\n isNamespaced() {\n return this.schema?.attributes?.namespaced || false;\n },\n\n labels: {\n get() {\n return this.value?.labels;\n },\n set(neu) {\n this.value.setLabels(neu);\n }\n },\n\n annotations: {\n get() {\n return this.value?.annotations;\n },\n set(neu) {\n this.value.setAnnotations(neu);\n }\n },\n\n doneRoute() {\n if ( this.value?.doneRoute ) {\n return this.value.doneRoute;\n }\n\n let name = this.$route.name;\n\n if ( name.endsWith('-id') ) {\n name = name.replace(/(-namespace)?-id$/, '');\n } else if ( name.endsWith('-create') ) {\n name = name.replace(/-create$/, '');\n }\n\n return name;\n },\n\n doneParams() {\n if ( this.value?.doneParams ) {\n return this.value.doneParams;\n }\n\n const out = { ...this.$route.params };\n\n delete out.namespace;\n delete out.id;\n\n return out;\n },\n\n },\n\n methods: {\n done() {\n if ( this.doneEvent ) {\n this.$emit('done');\n\n return;\n }\n\n if ( this.doneLocationOverride) {\n return this.$router.replace(this.doneLocationOverride);\n }\n\n if ( !this.doneRoute ) {\n return;\n }\n\n this.$router.replace({\n name: this.doneRoute,\n params: this.doneParams || { resource: this.value.type }\n });\n },\n\n // Detect and resolve conflicts from a 409 response.\n // If they are resolved, return a false-y value\n // Else they can't be resolved, return an array of errors to show to the user.\n conflict() {\n return handleConflict(this.initialValue.toJSON(), this.value, this.liveValue, this.$store.getters, this.$store);\n },\n\n async save(buttonDone, url, depth = 0) {\n if ( this.errors ) {\n clear(this.errors);\n }\n\n try {\n await this.applyHooks(BEFORE_SAVE_HOOKS);\n\n // Remove the labels map if it's empty\n if ( this.value?.metadata?.labels && Object.keys(this.value.metadata.labels || {}).length === 0 ) {\n delete this.value.metadata.labels;\n }\n\n // Remove the annotations map if it's empty\n if ( this.value?.metadata?.annotations && Object.keys(this.value.metadata.annotations || {}).length === 0 ) {\n delete this.value.metadata.annotations;\n }\n\n if ( this.isCreate ) {\n const ns = this.value?.metadata?.namespace;\n\n // Don't remember fleet-default as a target since the user isn't usually picking it explicitly\n if ( ns && ns !== DEFAULT_WORKSPACE ) {\n this.value.$dispatch('prefs/set', { key: LAST_NAMESPACE, value: ns }, { root: true });\n }\n }\n\n await this.actuallySave(url);\n\n // If spoofed we need to reload the values as the server can't have watchers for them.\n if (this.$store.getters['type-map/isSpoofed'](this.value.type)) {\n await this.$store.dispatch('cluster/findAll', { type: this.value.type, opt: { force: true } }, { root: true });\n }\n\n await this.applyHooks(AFTER_SAVE_HOOKS);\n buttonDone && buttonDone(true);\n\n this.done();\n } catch (err) {\n // Conflict, the resource being edited has changed since starting editing\n if ( err.status === 409 && depth === 0 && this.isEdit) {\n const errors = this.conflict();\n\n if ( errors === false ) {\n // It was automatically figured out, save again\n return this.save(buttonDone, url, depth + 1);\n } else {\n this.errors = errors;\n }\n } else {\n this.errors = exceptionToErrorsArray(err);\n }\n // Provide a stack trace for easier debugging of save errors\n console.error('CreateEditView mixin failed to save: ', err); // eslint-disable-line no-console\n buttonDone && buttonDone(false);\n }\n },\n\n async actuallySave(url) {\n if ( this.isCreate ) {\n url = url || this.schema.linkFor('collection');\n const res = await this.value.save({ url });\n\n if (res) {\n Object.assign(this.value, res);\n }\n } else {\n await this.value.save();\n }\n },\n\n setErrors(errors) {\n this.errors = errors;\n }\n },\n};\n","import { _EDIT, _YAML } from '@shell/config/query-params';\nimport Vue from 'vue';\n\nimport impl from './impl';\n\nexport default Vue.extend({\n ...impl,\n\n props: {\n mode: {\n type: String,\n default: _EDIT,\n },\n\n realMode: {\n type: String,\n default: _EDIT,\n },\n\n as: {\n type: String,\n default: _YAML,\n },\n\n // The model to be manipulated by the form\n value: {\n type: Object,\n required: true,\n },\n\n // A clone of the model before it's been changed, for conflict resolution\n initialValue: {\n type: Object,\n default: null,\n },\n\n // The 'live' equivalent of this model in the store\n liveValue: {\n type: Object,\n default: null,\n },\n\n doneEvent: {\n type: Boolean,\n default: false,\n },\n },\n});\n","import Vue from 'vue';\nimport { MANAGEMENT, STEVE } from '@shell/config/types';\nimport { clone } from '@shell/utils/object';\nimport { SETTING } from '@shell/config/settings';\n\nconst definitions = {};\n/**\n * Key/value of prefrences are stored before login here and cookies due lack of access permission.\n * Once user is logged in while setting asUserPreference, update stored before login Key/value to the backend in loadServer function.\n */\nlet prefsBeforeLogin = {};\n\nexport const create = function(name, def, opt = {}) {\n const parseJSON = opt.parseJSON === true;\n const asCookie = opt.asCookie === true;\n const asUserPreference = opt.asUserPreference !== false;\n const options = opt.options;\n const inheritFrom = opt.inheritFrom;\n\n definitions[name] = {\n def,\n options,\n parseJSON,\n asCookie,\n asUserPreference,\n inheritFrom, // if value is not defined on server, we can default it to another pref\n mangleRead: opt.mangleRead, // Alter the value read from the API (to match old Rancher expectations)\n mangleWrite: opt.mangleWrite, // Alter the value written back to the API (ditto)\n };\n\n return name;\n};\n\nexport const mapPref = function(name) {\n return {\n get() {\n return this.$store.getters['prefs/get'](name);\n },\n\n set(value) {\n this.$store.dispatch('prefs/set', { key: name, value });\n }\n };\n};\n\n// --------------------\nconst parseJSON = true; // Shortcut for setting it below\nconst asCookie = true; // Store as a cookie so that it's available before auth + on server-side\n\n// Keys must be lowercase and valid dns label (a-z 0-9 -)\nexport const CLUSTER = create('cluster', '');\nexport const LAST_NAMESPACE = create('last-namespace', '');\nexport const NAMESPACE_FILTERS = create('ns-by-cluster', {}, { parseJSON });\nexport const WORKSPACE = create('workspace', '');\nexport const EXPANDED_GROUPS = create('open-groups', ['cluster', 'policy', 'rbac', 'serviceDiscovery', 'storage', 'workload'], { parseJSON });\nexport const FAVORITE_TYPES = create('fav-type', [], { parseJSON });\nexport const GROUP_RESOURCES = create('group-by', 'namespace');\nexport const DIFF = create('diff', 'unified', { options: ['unified', 'split'] });\nexport const THEME = create('theme', 'auto', {\n options: ['light', 'auto', 'dark'],\n asCookie,\n parseJSON,\n mangleRead: x => x.replace(/^ui-/, ''),\n mangleWrite: x => `ui-${ x }`,\n});\nexport const PREFERS_SCHEME = create('pcs', '', { asCookie, asUserPreference: false });\nexport const LOCALE = create('locale', 'en-us', { asCookie });\nexport const KEYMAP = create('keymap', 'sublime', { options: ['sublime', 'emacs', 'vim'] });\nexport const ROWS_PER_PAGE = create('per-page', 100, { options: [10, 25, 50, 100], parseJSON });\nexport const LOGS_WRAP = create('logs-wrap', true, { parseJSON });\nexport const LOGS_TIME = create('logs-time', true, { parseJSON });\nexport const LOGS_RANGE = create('logs-range', '30 minutes', { parseJSON });\nexport const HIDE_REPOS = create('hide-repos', [], { parseJSON });\nexport const HIDE_DESC = create('hide-desc', [], { parseJSON });\nexport const HIDE_SENSITIVE = create('hide-sensitive', true, { options: [true, false], parseJSON });\nexport const SHOW_PRE_RELEASE = create('show-pre-release', false, { options: [false, true], parseJSON });\nexport const SHOW_CHART_MODE = create('chart-mode', 'featured', { parseJSON });\n\nexport const DATE_FORMAT = create('date-format', 'ddd, MMM D YYYY', {\n options: [\n 'ddd, MMM D YYYY',\n 'ddd, D MMM YYYY',\n 'D/M/YYYY',\n 'M/D/YYYY',\n 'YYYY-MM-DD'\n ]\n});\n\nexport const TIME_FORMAT = create('time-format', 'h:mm:ss a', {\n options: [\n 'h:mm:ss a',\n 'HH:mm:ss'\n ]\n});\n\nexport const TIME_ZONE = create('time-zone', 'local');\n// DEV will be deprecated on v2.7.0, but is needed so that we can grab the value for the new settings that derived from it\n// such as: VIEW_IN_API, ALL_NAMESPACES, THEME_SHORTCUT\nexport const DEV = create('dev', false, { parseJSON });\nexport const VIEW_IN_API = create('view-in-api', false, { parseJSON, inheritFrom: DEV });\nexport const ALL_NAMESPACES = create('all-namespaces', false, { parseJSON, inheritFrom: DEV });\nexport const THEME_SHORTCUT = create('theme-shortcut', false, { parseJSON, inheritFrom: DEV });\nexport const LAST_VISITED = create('last-visited', 'home', { parseJSON });\nexport const SEEN_WHATS_NEW = create('seen-whatsnew', '', { parseJSON });\nexport const READ_WHATS_NEW = create('read-whatsnew', '', { parseJSON });\nexport const AFTER_LOGIN_ROUTE = create('after-login-route', 'home', { parseJSON } );\nexport const HIDE_HOME_PAGE_CARDS = create('home-page-cards', {}, { parseJSON } );\nexport const PLUGIN_DEVELOPER = create('plugin-developer', false, { parseJSON, inheritFrom: DEV }); // Is the user a plugin developer?\n\nexport const _RKE1 = 'rke1';\nexport const _RKE2 = 'rke2';\nexport const PROVISIONER = create('provisioner', _RKE2, { options: [_RKE1, _RKE2] });\n\n// Promo for Cluster Tools feature on Cluster Dashboard page\nexport const CLUSTER_TOOLS_TIP = create('hide-cluster-tools-tip', false, { parseJSON });\n\n// Promo for Pod Security Policies (PSPs) being deprecated on kube version 1.25 on Cluster Dashboard page\nexport const PSP_DEPRECATION_BANNER = create('hide-psp-deprecation-banner', false, { parseJSON });\n\n// Maximum number of clusters to show in the slide-in menu\nexport const MENU_MAX_CLUSTERS = create('menu-max-clusters', 4, { options: [2, 3, 4, 5, 6, 7, 8, 9, 10], parseJSON });\n\n// Prompt for confirm when scaling down node pool in GUI and save the pref\nexport const SCALE_POOL_PROMPT = create('scale-pool-prompt', null, { parseJSON });\n// --------------------\n\nconst cookiePrefix = 'R_';\nconst cookieOptions = {\n maxAge: 365 * 86400,\n path: '/',\n sameSite: true,\n secure: true,\n};\n\nexport const state = function() {\n return {\n cookiesLoaded: false,\n data: {},\n definitions,\n };\n};\n\nexport const getters = {\n get: state => (key) => {\n const definition = state.definitions[key];\n\n if (!definition) {\n throw new Error(`Unknown preference: ${ key }`);\n }\n\n const user = state.data[key];\n\n if (user !== undefined) {\n return clone(user);\n }\n\n const def = clone(definition.def);\n\n return def;\n },\n\n defaultValue: state => (key) => {\n const definition = state.definitions[key];\n\n if (!definition) {\n throw new Error(`Unknown preference: ${ key }`);\n }\n\n return clone(definition.def);\n },\n\n options: state => (key) => {\n const definition = state.definitions[key];\n\n if (!definition) {\n throw new Error(`Unknown preference: ${ key }`);\n }\n\n if (!definition.options) {\n throw new Error(`Preference does not have options: ${ key }`);\n }\n\n return definition.options.slice();\n },\n\n theme: (state, getters, rootState, rootGetters) => {\n const setting = rootGetters['management/byId'](MANAGEMENT.SETTING, SETTING.THEME);\n\n if (setting?.value) {\n return setting?.value;\n }\n\n let theme = getters['get'](THEME);\n const pcs = getters['get'](PREFERS_SCHEME);\n\n // console.log('Get Theme', theme, pcs);\n\n // Ember UI uses this prefix\n if ( theme.startsWith('ui-') ) {\n theme = theme.substr(3);\n }\n\n if ( theme === 'auto' ) {\n if ( pcs === 'light' || pcs === 'dark' ) {\n return pcs;\n }\n\n return 'dark';\n }\n\n return theme;\n },\n\n afterLoginRoute: (state, getters) => {\n const afterLoginRoutePref = getters['get'](AFTER_LOGIN_ROUTE);\n\n if (typeof afterLoginRoutePref !== 'string') {\n return afterLoginRoutePref;\n }\n\n switch (true) {\n case (afterLoginRoutePref === 'home'):\n return { name: 'home' };\n case (afterLoginRoutePref === 'last-visited'): {\n const lastVisitedPref = getters['get'](LAST_VISITED);\n\n if (lastVisitedPref) {\n return lastVisitedPref;\n }\n const clusterPref = getters['get'](CLUSTER);\n\n return { name: 'c-cluster-explorer', params: { product: 'explorer', cluster: clusterPref } };\n }\n case (!!afterLoginRoutePref.match(/.+-dashboard$/)):\n {\n const clusterId = afterLoginRoutePref.split('-dashboard')[0];\n\n return { name: 'c-cluster-explorer', params: { product: 'explorer', cluster: clusterId } };\n }\n default:\n return { name: afterLoginRoutePref };\n }\n }\n};\n\nexport const mutations = {\n load(state, { key, value }) {\n Vue.set(state.data, key, value);\n },\n\n cookiesLoaded(state) {\n state.cookiesLoaded = true;\n },\n\n reset(state) {\n for (const key in state.definitions) {\n if ( state.definitions[key]?.asCookie ) {\n continue;\n }\n delete state.data[key];\n }\n },\n\n setDefinition(state, { name, definition = {} }) {\n state.definitions[name] = definition;\n },\n};\n\nexport const actions = {\n async set({\n dispatch, commit, rootGetters, state\n }, opt) {\n let { key, value } = opt; // eslint-disable-line prefer-const\n const definition = state.definitions[key];\n let server;\n\n if ( opt.val ) {\n throw new Error('Use value, not val');\n }\n\n commit('load', { key, value });\n\n if ( definition.asCookie ) {\n const opt = {\n ...cookieOptions,\n parseJSON: definition.parseJSON === true\n };\n\n this.$cookies.set(`${ cookiePrefix }${ key }`.toUpperCase(), value, opt);\n }\n\n if ( definition.asUserPreference ) {\n const checkLogin = rootGetters['auth/loggedIn'];\n\n // Check for login status\n if (!checkLogin) {\n prefsBeforeLogin[key] = value;\n\n return;\n }\n\n try {\n server = await dispatch('loadServer', key); // There's no watch on prefs, so get before set...\n\n if ( server?.data ) {\n if ( definition.mangleWrite ) {\n value = definition.mangleWrite(value);\n }\n\n if ( definition.parseJSON ) {\n Vue.set(server.data, key, JSON.stringify(value));\n } else {\n Vue.set(server.data, key, value);\n }\n\n await server.save({ redirectUnauthorized: false });\n }\n } catch (e) {\n // Well it failed, but not much to do about it...\n\n // Return the error\n return { type: e.type, status: e.status };\n }\n }\n },\n\n async setTheme({ dispatch }, val) {\n await dispatch('set', { key: THEME, value: val });\n },\n\n loadCookies({ state, commit }) {\n if ( state.cookiesLoaded ) {\n return;\n }\n\n for (const key in state.definitions) {\n const definition = state.definitions[key];\n\n if ( !definition.asCookie ) {\n continue;\n }\n\n const opt = { parseJSON: definition.parseJSON === true };\n const value = this.$cookies.get(`${ cookiePrefix }${ key }`.toUpperCase(), opt);\n\n if (value !== undefined) {\n commit('load', { key, value });\n }\n }\n\n commit('cookiesLoaded');\n },\n\n loadTheme({ state, dispatch }) {\n if ( process.client ) {\n const watchDark = window.matchMedia('(prefers-color-scheme: dark)');\n const watchLight = window.matchMedia('(prefers-color-scheme: light)');\n const watchNone = window.matchMedia('(prefers-color-scheme: no-preference)');\n\n const interval = 30 * 60 * 1000;\n const nextHalfHour = interval - Math.round(new Date().getTime()) % interval;\n\n setTimeout(() => {\n dispatch('loadTheme');\n }, nextHalfHour);\n // console.log('Update theme in', nextHalfHour, 'ms');\n\n if ( watchDark.matches ) {\n changed('dark');\n } else if ( watchLight.matches ) {\n changed('light');\n } else {\n changed(fromClock());\n }\n\n watchDark.addListener((e) => {\n if ( e.matches ) {\n changed('dark');\n }\n });\n\n watchLight.addListener((e) => {\n if ( e.matches ) {\n changed('light');\n }\n });\n\n watchNone.addListener((e) => {\n if ( e.matches ) {\n changed(fromClock());\n }\n });\n }\n\n function changed(value) {\n // console.log('Prefers Theme:', value);\n dispatch('set', { key: PREFERS_SCHEME, value });\n }\n\n function fromClock() {\n const hour = new Date().getHours();\n\n if ( hour < 7 || hour >= 18 ) {\n return 'dark';\n }\n\n return 'light';\n }\n },\n\n async loadServer( {\n state, dispatch, commit, rootState, rootGetters\n }, ignoreKey) {\n let server = { data: {} };\n\n try {\n const all = await dispatch('management/findAll', {\n type: STEVE.PREFERENCE,\n opt: {\n url: 'userpreferences',\n force: true,\n watch: false,\n redirectUnauthorized: false,\n stream: false,\n }\n }, { root: true });\n\n server = all?.[0];\n } catch (e) {\n console.error('Error loading preferences', e); // eslint-disable-line no-console\n\n return;\n }\n\n if ( !server?.data ) {\n return;\n }\n\n // if prefsBeforeLogin has values from login page, update the backend\n if (Object.keys(prefsBeforeLogin).length > 0) {\n Object.keys(prefsBeforeLogin).forEach((key) => {\n server.data[key] = prefsBeforeLogin[key];\n });\n\n await server.save({ redirectUnauthorized: false });\n\n // Clear prefsBeforeLogin, as we have now saved theses\n prefsBeforeLogin = {};\n }\n\n for (const key in state.definitions) {\n const definition = state.definitions[key];\n let value = clone(server.data[key]);\n\n if (value === undefined && definition.inheritFrom) {\n value = clone(server.data[definition.inheritFrom]);\n }\n\n if ( value === undefined || key === ignoreKey) {\n continue;\n }\n\n if ( definition.parseJSON ) {\n try {\n value = JSON.parse(value);\n } catch (err) {\n console.error('Error parsing server pref', key, value, err); // eslint-disable-line no-console\n continue;\n }\n }\n\n if ( definition.mangleRead ) {\n value = definition.mangleRead(value);\n }\n\n commit('load', { key, value });\n }\n\n return server;\n },\n\n setLastVisited({ state, dispatch, getters }, route) {\n if (!route) {\n return;\n }\n\n // Only save the last visited page if the user has that set as the login route preference\n const afterLoginRoutePref = getters['get'](AFTER_LOGIN_ROUTE);\n const doNotTrackLastVisited = typeof afterLoginRoutePref !== 'string' || afterLoginRoutePref !== 'last-visited';\n\n if (doNotTrackLastVisited) {\n return;\n }\n\n const toSave = getLoginRoute(route);\n\n return dispatch('set', { key: LAST_VISITED, value: toSave });\n },\n\n toggleTheme({ getters, dispatch }) {\n const value = getters[THEME] === 'light' ? 'dark' : 'light';\n\n return dispatch('set', { key: THEME, value });\n },\n\n setBrandStyle({ rootState, rootGetters }, dark = false) {\n if (rootState.managementReady) {\n try {\n const brandSetting = rootGetters['management/byId'](MANAGEMENT.SETTING, SETTING.BRAND);\n\n if (brandSetting && brandSetting.value && brandSetting.value !== '') {\n const brand = brandSetting.value;\n\n const brandMeta = require(`~shell/assets/brand/${ brand }/metadata.json`);\n const hasStylesheet = brandMeta.hasStylesheet === 'true';\n\n if (hasStylesheet) {\n document.body.classList.add(brand);\n } else {\n // TODO option apply color at runtime\n }\n }\n } catch {}\n }\n }\n};\n\nfunction getLoginRoute(route) {\n let parts = route.name?.split('-') || [];\n const params = {};\n const routeParams = route.params || {};\n\n // Find the 'resource' part of the route, if it is there\n const index = parts.findIndex(p => p === 'resource');\n\n if (index >= 0) {\n parts = parts.slice(0, index);\n }\n\n // Just keep the params that are needed\n parts.forEach((param) => {\n if (routeParams[param]) {\n params[param] = routeParams[param];\n }\n });\n\n return {\n name: parts.join('-'),\n params\n };\n}\n","// Imports\nvar ___CSS_LOADER_API_IMPORT___ = require(\"../../../@vue/cli-service/node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.id, \".clearfix[data-v-e765d1f4]:after,.clearfix[data-v-e765d1f4]:before{content:\\\" \\\";display:table}.clearfix[data-v-e765d1f4]:after{clear:both}.list-unstyled[data-v-e765d1f4]{margin:0;padding:0;list-style-type:none}.no-select[data-v-e765d1f4]{-webkit-user-select:none;-moz-user-select:none;user-select:none}.no-resize[data-v-e765d1f4]{resize:none}.hand[data-v-e765d1f4]{cursor:pointer;cursor:hand}.fixed[data-v-e765d1f4]{table-layout:fixed}.clip[data-v-e765d1f4]{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.clip[data-v-e765d1f4],.force-wrap[data-v-e765d1f4]{word-wrap:break-word}.force-wrap[data-v-e765d1f4]{white-space:normal}.bordered-section[data-v-e765d1f4]{border-bottom:1px solid var(--border);margin-bottom:20px;padding-bottom:20px}.section-divider[data-v-e765d1f4]{margin-bottom:20px;margin-top:20px}.overlay[data-v-e765d1f4]{align-items:center;background-color:var(--overlay-bg);display:flex;justify-content:center;position:absolute;bottom:0;top:0;left:0;right:0;text-align:center;z-index:51}.overlay-content-mode[data-v-e765d1f4],.overlay-main-mode[data-v-e765d1f4]{top:var(--header-height)}.overlay-content-mode[data-v-e765d1f4]{left:var(--nav-width)}\", \"\"]);\n// Exports\nmodule.exports = exports;\n","export { default as Banner } from './Banner.vue';\n","// style-loader: Adds some css to the DOM by adding a