@rancher/shell 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/assets/styles/app.scss +1 -1
  2. package/assets/styles/fonts/_fontstack.scss +11 -11
  3. package/assets/styles/vendor/vue-js-modal.scss +3 -3
  4. package/assets/translations/en-us.yaml +92 -22
  5. package/assets/translations/zh-hans.yaml +84 -15
  6. package/babel.config.js +13 -0
  7. package/chart/gatekeeper.vue +77 -0
  8. package/chart/istio.vue +108 -111
  9. package/chart/logging/index.vue +13 -4
  10. package/chart/monitoring/index.vue +15 -5
  11. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  12. package/chart/rancher-backup/index.vue +10 -3
  13. package/cloud-credential/aws.vue +1 -1
  14. package/cloud-credential/digitalocean.vue +1 -1
  15. package/cloud-credential/gcp.vue +1 -1
  16. package/cloud-credential/generic.vue +2 -2
  17. package/cloud-credential/linode.vue +1 -1
  18. package/cloud-credential/pnap.vue +1 -1
  19. package/components/ActionMenu.vue +3 -4
  20. package/components/AssignTo.vue +1 -1
  21. package/components/AsyncButton.vue +1 -1
  22. package/components/BannerGraphic.vue +1 -1
  23. package/components/ButtonDropdown.vue +2 -3
  24. package/components/ChartPsp.vue +76 -0
  25. package/components/CruResource.vue +6 -2
  26. package/components/DashboardMetrics.vue +12 -10
  27. package/components/DetailText.vue +1 -1
  28. package/components/DisableAuthProviderModal.vue +1 -1
  29. package/components/EmberPage.vue +1 -1
  30. package/components/EtcdInfoBanner.vue +5 -4
  31. package/components/ExplorerMembers.vue +1 -1
  32. package/components/ExplorerProjectsNamespaces.vue +14 -1
  33. package/components/FileDiff.vue +6 -7
  34. package/components/GrafanaDashboard.vue +18 -21
  35. package/components/LazyImage.vue +10 -12
  36. package/components/LogItem.vue +1 -1
  37. package/components/Markdown.vue +1 -1
  38. package/components/PromptRemove.vue +2 -2
  39. package/components/PromptRestore.vue +1 -1
  40. package/components/ResourceDetail/Masthead.vue +16 -0
  41. package/components/ResourceDetail/index.vue +21 -4
  42. package/components/ResourceList/index.vue +1 -1
  43. package/components/ResourceTable.vue +4 -1
  44. package/components/SingleClusterInfo.vue +2 -2
  45. package/components/SortableTable/THead.vue +1 -1
  46. package/components/SortableTable/index.vue +5 -2
  47. package/components/__tests__/AsyncButton.test.ts +3 -1
  48. package/components/__tests__/ChartPsp.test.ts +75 -0
  49. package/components/__tests__/CruResource.test.ts +3 -1
  50. package/components/auth/Principal.vue +1 -1
  51. package/components/fleet/FleetBundles.vue +3 -1
  52. package/components/fleet/FleetClusters.vue +1 -2
  53. package/components/fleet/FleetIntro.vue +9 -1
  54. package/components/fleet/FleetNoWorkspaces.vue +62 -0
  55. package/components/fleet/FleetSummary.vue +7 -1
  56. package/components/form/LabeledSelect.vue +14 -11
  57. package/components/form/MatchExpressions.vue +17 -2
  58. package/components/form/NameNsDescription.vue +31 -45
  59. package/components/form/ResourceSelector.vue +1 -1
  60. package/components/form/SecretSelector.vue +5 -1
  61. package/components/form/ServiceNameSelect.vue +1 -1
  62. package/components/form/SimpleSecretSelector.vue +9 -9
  63. package/components/form/__tests__/LabeledSelect.test.ts +138 -0
  64. package/components/form/__tests__/NameNsDescription.ts +32 -0
  65. package/components/formatter/InternalExternalIP.vue +6 -0
  66. package/components/formatter/InvolvedObjectLink.vue +54 -0
  67. package/components/formatter/Link.vue +20 -4
  68. package/components/formatter/LinkName.vue +6 -1
  69. package/components/formatter/ServiceTargets.vue +1 -1
  70. package/components/nav/Group.vue +2 -2
  71. package/components/nav/NamespaceFilter.vue +15 -11
  72. package/components/nav/TopLevelMenu.vue +2 -4
  73. package/components/nav/Type.vue +1 -1
  74. package/components/nav/WorkspaceSwitcher.vue +46 -5
  75. package/config/labels-annotations.js +17 -0
  76. package/config/product/auth.js +3 -2
  77. package/config/product/explorer.js +11 -4
  78. package/config/product/fleet.js +2 -0
  79. package/config/router.js +414 -0
  80. package/config/table-headers.js +10 -2
  81. package/config/types.js +11 -8
  82. package/config/uiplugins.js +30 -0
  83. package/content/docs/en-us/whats-new.md +10 -0
  84. package/content/docs/zh-hans/whats-new.md +11 -1
  85. package/core/plugin-routes.ts +23 -0
  86. package/creators/app/app.package.json +2 -1
  87. package/creators/app/files/.eslintrc.js +1 -1
  88. package/creators/app/files/babel.config.js +1 -18
  89. package/creators/app/files/vue.config.js +7 -0
  90. package/creators/app/init +5 -5
  91. package/creators/pkg/files/.github/workflows/build-extension.yml +111 -0
  92. package/creators/pkg/init +35 -4
  93. package/creators/update/init +1 -1
  94. package/detail/constraints.gatekeeper.sh.constraint.vue +20 -10
  95. package/detail/fleet.cattle.io.gitrepo.vue +19 -11
  96. package/detail/harvesterhci.io.management.cluster.vue +3 -3
  97. package/detail/provisioning.cattle.io.cluster.vue +54 -12
  98. package/detail/workload/index.vue +3 -3
  99. package/dialog/AddClusterMemberDialog.vue +1 -1
  100. package/dialog/AddProjectMemberDialog.vue +2 -2
  101. package/dialog/AddonConfigConfirmationDialog.vue +27 -15
  102. package/dialog/DiagnosticTimingsDialog.vue +1 -1
  103. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  104. package/dialog/GenericPrompt.vue +18 -6
  105. package/dialog/RotateEncryptionKeyDialog.vue +1 -1
  106. package/dialog/SaveAsRKETemplateDialog.vue +1 -1
  107. package/dialog/ScaleMachineDownDialog.vue +1 -1
  108. package/edit/auth/github.vue +8 -8
  109. package/edit/auth/googleoauth.vue +5 -5
  110. package/edit/auth/ldap/index.vue +1 -1
  111. package/edit/auth/oidc.vue +1 -1
  112. package/edit/auth/saml.vue +1 -1
  113. package/edit/cis.cattle.io.clusterscan.vue +1 -1
  114. package/edit/fleet.cattle.io.clustergroup.vue +6 -4
  115. package/edit/fleet.cattle.io.gitrepo.vue +16 -3
  116. package/edit/helm.cattle.io.projecthelmchart.vue +5 -1
  117. package/edit/management.cattle.io.fleetworkspace.vue +141 -6
  118. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +4 -1
  119. package/edit/management.cattle.io.setting.vue +1 -1
  120. package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +2 -2
  121. package/edit/monitoring.coreos.com.receiver/tls.vue +18 -18
  122. package/edit/monitoring.coreos.com.receiver/types/webhook.banner.vue +4 -4
  123. package/edit/monitoring.coreos.com.receiver/types/webhook.vue +1 -1
  124. package/edit/namespace.vue +2 -2
  125. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +126 -45
  126. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  127. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +10 -0
  128. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -0
  129. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +202 -2
  130. package/edit/provisioning.cattle.io.cluster/rke2.vue +248 -84
  131. package/edit/resources.cattle.io.backup.vue +1 -1
  132. package/edit/service.vue +1 -1
  133. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +2 -2
  134. package/edit/workload/__tests__/Job.test.ts +3 -1
  135. package/edit/workload/index.vue +8 -3
  136. package/edit/workload/mixins/workload.js +16 -0
  137. package/layouts/default.vue +7 -3
  138. package/list/fleet.cattle.io.bundle.vue +6 -3
  139. package/list/fleet.cattle.io.clusterregistrationtoken.vue +3 -1
  140. package/list/fleet.cattle.io.gitrepo.vue +44 -5
  141. package/list/management.cattle.io.fleetworkspace.vue +45 -0
  142. package/list/node.vue +69 -16
  143. package/list/provisioning.cattle.io.cluster.vue +30 -1
  144. package/machine-config/azure.vue +97 -38
  145. package/middleware/authenticated.js +34 -0
  146. package/mixins/chart.js +73 -2
  147. package/mixins/resource-fetch.js +2 -2
  148. package/models/apps.statefulset.js +28 -0
  149. package/models/cluster/node.js +23 -2
  150. package/models/cluster.x-k8s.io.machine.js +4 -2
  151. package/models/clusterroletemplatebinding.js +7 -0
  152. package/models/constraints.gatekeeper.sh.constraint.js +9 -0
  153. package/models/fleet.cattle.io.cluster.js +19 -10
  154. package/models/fleet.cattle.io.gitrepo.js +7 -2
  155. package/models/management.cattle.io.cluster.js +1 -1
  156. package/models/management.cattle.io.fleetworkspace.js +12 -0
  157. package/models/management.cattle.io.gitreporestriction.js +5 -0
  158. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.js +3 -0
  159. package/models/provisioning.cattle.io.cluster.js +7 -5
  160. package/nuxt/App.js +210 -0
  161. package/nuxt/axios.js +186 -0
  162. package/nuxt/client.js +817 -0
  163. package/nuxt/components/nuxt-build-indicator.vue +143 -0
  164. package/nuxt/components/nuxt-child.js +122 -0
  165. package/nuxt/components/nuxt-error.vue +98 -0
  166. package/nuxt/components/nuxt-link.client.js +98 -0
  167. package/nuxt/components/nuxt-link.server.js +16 -0
  168. package/nuxt/components/nuxt-loading.vue +154 -0
  169. package/nuxt/components/nuxt.js +101 -0
  170. package/nuxt/cookie-universal-nuxt.js +9 -0
  171. package/nuxt/empty.js +1 -0
  172. package/nuxt/index.js +365 -0
  173. package/nuxt/jsonp.js +82 -0
  174. package/nuxt/loading.html +39 -0
  175. package/nuxt/middleware.js +12 -0
  176. package/nuxt/mixins/fetch.client.js +90 -0
  177. package/nuxt/mixins/fetch.server.js +69 -0
  178. package/nuxt/portal-vue.js +4 -0
  179. package/nuxt/server.js +312 -0
  180. package/nuxt/store.js +178 -0
  181. package/nuxt/utils.js +630 -0
  182. package/nuxt/views/app.template.html +9 -0
  183. package/nuxt/views/error.html +23 -0
  184. package/package.json +5 -9
  185. package/pages/auth/setup.vue +2 -2
  186. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +33 -0
  187. package/pages/c/_cluster/apps/charts/chart.vue +4 -4
  188. package/pages/c/_cluster/apps/charts/install.helpers.js +26 -0
  189. package/pages/c/_cluster/apps/charts/install.vue +40 -66
  190. package/pages/c/_cluster/explorer/EventsTable.vue +5 -19
  191. package/pages/c/_cluster/explorer/index.vue +29 -25
  192. package/pages/c/_cluster/explorer/tools/index.vue +8 -8
  193. package/pages/c/_cluster/fleet/index.vue +95 -34
  194. package/pages/c/_cluster/gatekeeper/index.vue +1 -1
  195. package/pages/c/_cluster/istio/index.vue +5 -5
  196. package/pages/c/_cluster/manager/cloudCredential/index.vue +1 -1
  197. package/pages/c/_cluster/monitoring/index.vue +7 -0
  198. package/pages/c/_cluster/uiplugins/InstallDialog.vue +8 -8
  199. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +20 -7
  200. package/pages/c/_cluster/uiplugins/index.vue +49 -17
  201. package/pages/home.vue +9 -4
  202. package/pages/index.vue +10 -1
  203. package/plugins/clean-html-directive.js +31 -0
  204. package/plugins/dashboard-store/actions.js +32 -9
  205. package/plugins/dashboard-store/mutations.js +5 -2
  206. package/plugins/dashboard-store/resource-class.js +8 -1
  207. package/plugins/steve/mutations.js +3 -2
  208. package/plugins/steve/steve-description-class.js +5 -1
  209. package/plugins/steve/subscribe.js +63 -54
  210. package/plugins/steve-create-worker.js +14 -0
  211. package/promptRemove/management.cattle.io.globalrole.vue +2 -2
  212. package/promptRemove/management.cattle.io.project.vue +2 -2
  213. package/promptRemove/management.cattle.io.roletemplate.vue +2 -2
  214. package/promptRemove/pod.vue +1 -1
  215. package/public/index.html +65 -0
  216. package/rancher-components/components/Banner/Banner.test.ts +9 -1
  217. package/rancher-components/components/Banner/Banner.vue +1 -1
  218. package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -0
  219. package/rancher-components/components/Form/Radio/RadioButton.vue +1 -1
  220. package/scripts/build-pkg.sh +1 -0
  221. package/scripts/clean +6 -0
  222. package/scripts/extension/bundle +58 -0
  223. package/scripts/extension/helmpatch +89 -0
  224. package/scripts/extension/publish +314 -0
  225. package/scripts/test-plugins-build.sh +4 -0
  226. package/store/__tests__/index.test.ts +110 -0
  227. package/store/index.js +145 -58
  228. package/store/type-map.js +5 -1
  229. package/tsconfig.default.json +36 -0
  230. package/tsconfig.json +24 -0
  231. package/types/shell/index.d.ts +420 -343
  232. package/utils/__tests__/string.test.ts +12 -0
  233. package/utils/auth.js +65 -0
  234. package/utils/monitoring.js +2 -1
  235. package/utils/position.js +5 -8
  236. package/utils/router.scrollBehavior.js +80 -0
  237. package/utils/select.js +1 -3
  238. package/utils/socket.js +1 -0
  239. package/utils/string.js +13 -0
  240. package/utils/time.js +9 -0
  241. package/vue.config.js +679 -0
  242. package/chart/rancher-alerting-drivers.vue +0 -53
  243. package/chart/rancher-gatekeeper.vue +0 -37
  244. package/creators/app/files/nuxt.config.js +0 -6
  245. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +0 -4
  246. package/nuxt.config.js +0 -798
@@ -0,0 +1,143 @@
1
+ <template>
2
+ <transition appear>
3
+ <div v-if="building" class="nuxt__build_indicator" :style="indicatorStyle">
4
+ <svg viewBox="0 0 96 72" version="1" xmlns="http://www.w3.org/2000/svg">
5
+ <g fill="none" fill-rule="evenodd">
6
+ <path d="M6 66h23l1-3 21-37L40 6 6 66zM79 66h11L62 17l-5 9 22 37v3zM54 31L35 66h38z" />
7
+ <path d="M29 69v-1-2H6L40 6l11 20 3-6L44 3s-2-3-4-3-3 1-5 3L1 63c0 1-2 3 0 6 0 1 2 2 5 2h28c-3 0-4-1-5-2z" fill="#00C58E" />
8
+ <path d="M95 63L67 14c0-1-2-3-5-3-1 0-3 0-4 3l-4 6 3 6 5-9 28 49H79a5 5 0 0 1 0 3c-2 2-5 2-5 2h16c1 0 4 0 5-2 1-1 2-3 0-6z" fill="#00C58E" />
9
+ <path d="M79 69v-1-2-3L57 26l-3-6-3 6-21 37-1 3a5 5 0 0 0 0 3c1 1 2 2 5 2h40s3 0 5-2zM54 31l19 35H35l19-35z" fill="#FFF" fill-rule="nonzero" />
10
+ </g>
11
+ </svg>
12
+ {{ animatedProgress }}%
13
+ </div>
14
+ </transition>
15
+ </template>
16
+
17
+ <script>
18
+ export default {
19
+ name: 'NuxtBuildIndicator',
20
+ data () {
21
+ return {
22
+ building: false,
23
+ progress: 0,
24
+ animatedProgress: 0,
25
+ reconnectAttempts: 0
26
+ }
27
+ },
28
+ computed: {
29
+ options: () => ({"position":"bottom-right","backgroundColor":"#2E495E","color":"#00C48D"}),
30
+ indicatorStyle () {
31
+ const [d1, d2] = this.options.position.split('-')
32
+ return {
33
+ [d1]: '20px',
34
+ [d2]: '20px',
35
+ 'background-color': this.options.backgroundColor,
36
+ color: this.options.color
37
+ }
38
+ }
39
+ },
40
+ watch: {
41
+ progress (val, oldVal) {
42
+ // Average progress may decrease but ignore it!
43
+ if (val < oldVal) {
44
+ return
45
+ }
46
+ // Cancel old animation
47
+ clearInterval(this._progressAnimation)
48
+ // Jump to edge immediately
49
+ if (val < 10 || val > 90) {
50
+ this.animatedProgress = val
51
+ return
52
+ }
53
+ // Animate to value
54
+ this._progressAnimation = setInterval(() => {
55
+ const diff = this.progress - this.animatedProgress
56
+ if (diff > 0) {
57
+ this.animatedProgress++
58
+ } else {
59
+ clearInterval(this._progressAnimation)
60
+ }
61
+ }, 50)
62
+ }
63
+ },
64
+ mounted () {
65
+ if (EventSource === undefined) {
66
+ return // Unsupported
67
+ }
68
+ this.sseConnect()
69
+ },
70
+ beforeDestroy () {
71
+ this.sseClose()
72
+ clearInterval(this._progressAnimation)
73
+ },
74
+ methods: {
75
+ sseConnect () {
76
+ if (this._connecting) {
77
+ return
78
+ }
79
+ this._connecting = true
80
+ this.sse = new EventSource('/_loading/sse')
81
+ this.sse.addEventListener('message', event => this.onSseMessage(event))
82
+ },
83
+ onSseMessage (message) {
84
+ const data = JSON.parse(message.data)
85
+ if (!data.states) {
86
+ return
87
+ }
88
+
89
+ this.progress = Math.round(data.states.reduce((p, s) => p + s.progress, 0) / data.states.length)
90
+
91
+ if (!data.allDone) {
92
+ this.building = true
93
+ } else {
94
+ this.$nextTick(() => {
95
+ this.building = false
96
+ this.animatedProgress = 0
97
+ this.progress = 0
98
+ clearInterval(this._progressAnimation)
99
+ })
100
+ }
101
+ },
102
+
103
+ sseClose () {
104
+ if (this.sse) {
105
+ this.sse.close()
106
+ delete this.sse
107
+ }
108
+ }
109
+ }
110
+ }
111
+ </script>
112
+
113
+ <style scoped>
114
+ .nuxt__build_indicator {
115
+ box-sizing: border-box;
116
+ position: fixed;
117
+ font-family: monospace;
118
+ padding: 5px 10px;
119
+ border-radius: 5px;
120
+ box-shadow: 1px 1px 2px 0px rgba(0,0,0,0.2);
121
+ width: 88px;
122
+ z-index: 2147483647;
123
+ font-size: 16px;
124
+ line-height: 1.2rem;
125
+ }
126
+ .v-enter-active, .v-leave-active {
127
+ transition-delay: 0.2s;
128
+ transition-property: all;
129
+ transition-duration: 0.3s;
130
+ }
131
+ .v-leave-to {
132
+ opacity: 0;
133
+ transform: translateY(20px);
134
+ }
135
+ svg {
136
+ display: inline-block;
137
+ vertical-align: baseline;
138
+ width: 1.1em;
139
+ height: 0.825em;
140
+ position: relative;
141
+ top: 1px;
142
+ }
143
+ </style>
@@ -0,0 +1,122 @@
1
+
2
+ export default {
3
+ name: 'NuxtChild',
4
+ functional: true,
5
+ props: {
6
+ nuxtChildKey: {
7
+ type: String,
8
+ default: ''
9
+ },
10
+ keepAlive: Boolean,
11
+ keepAliveProps: {
12
+ type: Object,
13
+ default: undefined
14
+ }
15
+ },
16
+ render (_, { parent, data, props }) {
17
+ const h = parent.$createElement
18
+
19
+ data.nuxtChild = true
20
+ const _parent = parent
21
+ const transitions = parent.$nuxt.nuxt.transitions
22
+ const defaultTransition = parent.$nuxt.nuxt.defaultTransition
23
+
24
+ let depth = 0
25
+ while (parent) {
26
+ if (parent.$vnode && parent.$vnode.data.nuxtChild) {
27
+ depth++
28
+ }
29
+ parent = parent.$parent
30
+ }
31
+ data.nuxtChildDepth = depth
32
+ const transition = transitions[depth] || defaultTransition
33
+ const transitionProps = {}
34
+ transitionsKeys.forEach((key) => {
35
+ if (typeof transition[key] !== 'undefined') {
36
+ transitionProps[key] = transition[key]
37
+ }
38
+ })
39
+
40
+ const listeners = {}
41
+ listenersKeys.forEach((key) => {
42
+ if (typeof transition[key] === 'function') {
43
+ listeners[key] = transition[key].bind(_parent)
44
+ }
45
+ })
46
+ if (process.client) {
47
+ // Add triggerScroll event on beforeEnter (fix #1376)
48
+ const beforeEnter = listeners.beforeEnter
49
+ listeners.beforeEnter = (el) => {
50
+ // Ensure to trigger scroll event after calling scrollBehavior
51
+ window.$nuxt.$nextTick(() => {
52
+ window.$nuxt.$emit('triggerScroll')
53
+ })
54
+ if (beforeEnter) {
55
+ return beforeEnter.call(_parent, el)
56
+ }
57
+ }
58
+ }
59
+
60
+ // make sure that leave is called asynchronous (fix #5703)
61
+ if (transition.css === false) {
62
+ const leave = listeners.leave
63
+
64
+ // only add leave listener when user didnt provide one
65
+ // or when it misses the done argument
66
+ if (!leave || leave.length < 2) {
67
+ listeners.leave = (el, done) => {
68
+ if (leave) {
69
+ leave.call(_parent, el)
70
+ }
71
+
72
+ _parent.$nextTick(done)
73
+ }
74
+ }
75
+ }
76
+
77
+ let routerView = h('routerView', data)
78
+
79
+ if (props.keepAlive) {
80
+ routerView = h('keep-alive', { props: props.keepAliveProps }, [routerView])
81
+ }
82
+
83
+ return h('transition', {
84
+ props: transitionProps,
85
+ on: listeners
86
+ }, [routerView])
87
+ }
88
+ }
89
+
90
+ const transitionsKeys = [
91
+ 'name',
92
+ 'mode',
93
+ 'appear',
94
+ 'css',
95
+ 'type',
96
+ 'duration',
97
+ 'enterClass',
98
+ 'leaveClass',
99
+ 'appearClass',
100
+ 'enterActiveClass',
101
+ 'enterActiveClass',
102
+ 'leaveActiveClass',
103
+ 'appearActiveClass',
104
+ 'enterToClass',
105
+ 'leaveToClass',
106
+ 'appearToClass'
107
+ ]
108
+
109
+ const listenersKeys = [
110
+ 'beforeEnter',
111
+ 'enter',
112
+ 'afterEnter',
113
+ 'enterCancelled',
114
+ 'beforeLeave',
115
+ 'leave',
116
+ 'afterLeave',
117
+ 'leaveCancelled',
118
+ 'beforeAppear',
119
+ 'appear',
120
+ 'afterAppear',
121
+ 'appearCancelled'
122
+ ]
@@ -0,0 +1,98 @@
1
+ <template>
2
+ <div class="__nuxt-error-page">
3
+ <div class="error">
4
+ <svg xmlns="http://www.w3.org/2000/svg" width="90" height="90" fill="#DBE1EC" viewBox="0 0 48 48">
5
+ <path d="M22 30h4v4h-4zm0-16h4v12h-4zm1.99-10C12.94 4 4 12.95 4 24s8.94 20 19.99 20S44 35.05 44 24 35.04 4 23.99 4zM24 40c-8.84 0-16-7.16-16-16S15.16 8 24 8s16 7.16 16 16-7.16 16-16 16z" />
6
+ </svg>
7
+
8
+ <div class="title">{{ message }}</div>
9
+ <p v-if="statusCode === 404" class="description">
10
+ <a v-if="typeof $route === 'undefined'" class="error-link" href="/"></a>
11
+ <NuxtLink v-else class="error-link" to="/">Back to the home page</NuxtLink>
12
+ </p>
13
+
14
+ <p class="description" v-else>An error occurred while rendering the page. Check developer tools console for details.</p>
15
+
16
+ <div class="logo">
17
+ <a href="https://nuxtjs.org" target="_blank" rel="noopener">Nuxt</a>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script>
24
+ export default {
25
+ name: 'NuxtError',
26
+ props: {
27
+ error: {
28
+ type: Object,
29
+ default: null
30
+ }
31
+ },
32
+ computed: {
33
+ statusCode () {
34
+ return (this.error && this.error.statusCode) || 500
35
+ },
36
+ message () {
37
+ return this.error.message || 'Error'
38
+ }
39
+ },
40
+ head () {
41
+ return {
42
+ title: this.message,
43
+ meta: [
44
+ {
45
+ name: 'viewport',
46
+ content: 'width=device-width,initial-scale=1.0,minimum-scale=1.0'
47
+ }
48
+ ]
49
+ }
50
+ }
51
+ }
52
+ </script>
53
+
54
+ <style>
55
+ .__nuxt-error-page {
56
+ padding: 1rem;
57
+ background: #F7F8FB;
58
+ color: #47494E;
59
+ text-align: center;
60
+ display: flex;
61
+ justify-content: center;
62
+ align-items: center;
63
+ flex-direction: column;
64
+ font-family: sans-serif;
65
+ font-weight: 100 !important;
66
+ -ms-text-size-adjust: 100%;
67
+ -webkit-text-size-adjust: 100%;
68
+ -webkit-font-smoothing: antialiased;
69
+ position: absolute;
70
+ top: 0;
71
+ left: 0;
72
+ right: 0;
73
+ bottom: 0;
74
+ }
75
+ .__nuxt-error-page .error {
76
+ max-width: 450px;
77
+ }
78
+ .__nuxt-error-page .title {
79
+ font-size: 1.5rem;
80
+ margin-top: 15px;
81
+ color: #47494E;
82
+ margin-bottom: 8px;
83
+ }
84
+ .__nuxt-error-page .description {
85
+ color: #7F828B;
86
+ line-height: 21px;
87
+ margin-bottom: 10px;
88
+ }
89
+ .__nuxt-error-page a {
90
+ color: #7F828B !important;
91
+ text-decoration: none;
92
+ }
93
+ .__nuxt-error-page .logo {
94
+ position: fixed;
95
+ left: 12px;
96
+ bottom: 12px;
97
+ }
98
+ </style>
@@ -0,0 +1,98 @@
1
+ import Vue from 'vue'
2
+
3
+ const requestIdleCallback = window.requestIdleCallback ||
4
+ function (cb) {
5
+ const start = Date.now()
6
+ return setTimeout(function () {
7
+ cb({
8
+ didTimeout: false,
9
+ timeRemaining: () => Math.max(0, 50 - (Date.now() - start))
10
+ })
11
+ }, 1)
12
+ }
13
+
14
+ const cancelIdleCallback = window.cancelIdleCallback || function (id) {
15
+ clearTimeout(id)
16
+ }
17
+
18
+ const observer = window.IntersectionObserver && new window.IntersectionObserver((entries) => {
19
+ entries.forEach(({ intersectionRatio, target: link }) => {
20
+ if (intersectionRatio <= 0 || !link.__prefetch) {
21
+ return
22
+ }
23
+ link.__prefetch()
24
+ })
25
+ })
26
+
27
+ export default {
28
+ name: 'NuxtLink',
29
+ extends: Vue.component('RouterLink'),
30
+ props: {
31
+ prefetch: {
32
+ type: Boolean,
33
+ default: false
34
+ },
35
+ noPrefetch: {
36
+ type: Boolean,
37
+ default: false
38
+ }
39
+ },
40
+ mounted () {
41
+ if (this.prefetch && !this.noPrefetch) {
42
+ this.handleId = requestIdleCallback(this.observe, { timeout: 2e3 })
43
+ }
44
+ },
45
+ beforeDestroy () {
46
+ cancelIdleCallback(this.handleId)
47
+
48
+ if (this.__observed) {
49
+ observer.unobserve(this.$el)
50
+ delete this.$el.__prefetch
51
+ }
52
+ },
53
+ methods: {
54
+ observe () {
55
+ // If no IntersectionObserver, avoid prefetching
56
+ if (!observer) {
57
+ return
58
+ }
59
+ // Add to observer
60
+ if (this.shouldPrefetch()) {
61
+ this.$el.__prefetch = this.prefetchLink.bind(this)
62
+ observer.observe(this.$el)
63
+ this.__observed = true
64
+ }
65
+ },
66
+ shouldPrefetch () {
67
+ return this.getPrefetchComponents().length > 0
68
+ },
69
+ canPrefetch () {
70
+ const conn = navigator.connection
71
+ const hasBadConnection = this.$nuxt.isOffline || (conn && ((conn.effectiveType || '').includes('2g') || conn.saveData))
72
+
73
+ return !hasBadConnection
74
+ },
75
+ getPrefetchComponents () {
76
+ const ref = this.$router.resolve(this.to, this.$route, this.append)
77
+ const Components = ref.resolved.matched.map(r => r.components.default)
78
+
79
+ return Components.filter(Component => typeof Component === 'function' && !Component.options && !Component.__prefetched)
80
+ },
81
+ prefetchLink () {
82
+ if (!this.canPrefetch()) {
83
+ return
84
+ }
85
+ // Stop observing this link (in case of internet connection changes)
86
+ observer.unobserve(this.$el)
87
+ const Components = this.getPrefetchComponents()
88
+
89
+ for (const Component of Components) {
90
+ const componentOrPromise = Component()
91
+ if (componentOrPromise instanceof Promise) {
92
+ componentOrPromise.catch(() => {})
93
+ }
94
+ Component.__prefetched = true
95
+ }
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,16 @@
1
+ import Vue from 'vue'
2
+
3
+ export default {
4
+ name: 'NuxtLink',
5
+ extends: Vue.component('RouterLink'),
6
+ props: {
7
+ prefetch: {
8
+ type: Boolean,
9
+ default: false
10
+ },
11
+ noPrefetch: {
12
+ type: Boolean,
13
+ default: false
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,154 @@
1
+ <script>
2
+ export default {
3
+ name: 'NuxtLoading',
4
+ data () {
5
+ return {
6
+ percent: 0,
7
+ show: false,
8
+ canSucceed: true,
9
+ reversed: false,
10
+ skipTimerCount: 0,
11
+ rtl: false,
12
+ throttle: 200,
13
+ duration: 3000,
14
+ continuous: false
15
+ }
16
+ },
17
+ computed: {
18
+ left () {
19
+ if (!this.continuous && !this.rtl) {
20
+ return false
21
+ }
22
+ return this.rtl
23
+ ? (this.reversed ? '0px' : 'auto')
24
+ : (!this.reversed ? '0px' : 'auto')
25
+ }
26
+ },
27
+ beforeDestroy () {
28
+ this.clear()
29
+ },
30
+ methods: {
31
+ clear () {
32
+ clearInterval(this._timer)
33
+ clearTimeout(this._throttle)
34
+ this._timer = null
35
+ },
36
+ start () {
37
+ this.clear()
38
+ this.percent = 0
39
+ this.reversed = false
40
+ this.skipTimerCount = 0
41
+ this.canSucceed = true
42
+
43
+ if (this.throttle) {
44
+ this._throttle = setTimeout(() => this.startTimer(), this.throttle)
45
+ } else {
46
+ this.startTimer()
47
+ }
48
+ return this
49
+ },
50
+ set (num) {
51
+ this.show = true
52
+ this.canSucceed = true
53
+ this.percent = Math.min(100, Math.max(0, Math.floor(num)))
54
+ return this
55
+ },
56
+ get () {
57
+ return this.percent
58
+ },
59
+ increase (num) {
60
+ this.percent = Math.min(100, Math.floor(this.percent + num))
61
+ return this
62
+ },
63
+ decrease (num) {
64
+ this.percent = Math.max(0, Math.floor(this.percent - num))
65
+ return this
66
+ },
67
+ pause () {
68
+ clearInterval(this._timer)
69
+ return this
70
+ },
71
+ resume () {
72
+ this.startTimer()
73
+ return this
74
+ },
75
+ finish () {
76
+ this.percent = this.reversed ? 0 : 100
77
+ this.hide()
78
+ return this
79
+ },
80
+ hide () {
81
+ this.clear()
82
+ setTimeout(() => {
83
+ this.show = false
84
+ this.$nextTick(() => {
85
+ this.percent = 0
86
+ this.reversed = false
87
+ })
88
+ }, 500)
89
+ return this
90
+ },
91
+ fail (error) {
92
+ this.canSucceed = false
93
+ return this
94
+ },
95
+ startTimer () {
96
+ if (!this.show) {
97
+ this.show = true
98
+ }
99
+ if (typeof this._cut === 'undefined') {
100
+ this._cut = 10000 / Math.floor(this.duration)
101
+ }
102
+
103
+ this._timer = setInterval(() => {
104
+ /**
105
+ * When reversing direction skip one timers
106
+ * so 0, 100 are displayed for two iterations
107
+ * also disable css width transitioning
108
+ * which otherwise interferes and shows
109
+ * a jojo effect
110
+ */
111
+ if (this.skipTimerCount > 0) {
112
+ this.skipTimerCount--
113
+ return
114
+ }
115
+
116
+ if (this.reversed) {
117
+ this.decrease(this._cut)
118
+ } else {
119
+ this.increase(this._cut)
120
+ }
121
+
122
+ if (this.continuous) {
123
+ if (this.percent >= 100) {
124
+ this.skipTimerCount = 1
125
+
126
+ this.reversed = !this.reversed
127
+ } else if (this.percent <= 0) {
128
+ this.skipTimerCount = 1
129
+
130
+ this.reversed = !this.reversed
131
+ }
132
+ }
133
+ }, 100)
134
+ }
135
+ },
136
+ render (h) {
137
+ let el = h(false)
138
+ if (this.show) {
139
+ el = h('div', {
140
+ staticClass: 'nuxt-progress',
141
+ class: {
142
+ 'nuxt-progress-notransition': this.skipTimerCount > 0,
143
+ 'nuxt-progress-failed': !this.canSucceed
144
+ },
145
+ style: {
146
+ width: this.percent + '%',
147
+ left: this.left
148
+ }
149
+ })
150
+ }
151
+ return el
152
+ }
153
+ }
154
+ </script>