@rancher/shell 0.3.0 → 0.3.1
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.
- package/assets/styles/global/_button.scss +5 -1
- package/assets/styles/global/_columns.scss +4 -0
- package/assets/styles/global/_layout.scss +1 -2
- package/assets/styles/global/_select.scss +1 -4
- package/assets/styles/themes/_dark.scss +4 -4
- package/assets/styles/themes/_light.scss +4 -3
- package/assets/styles/themes/_suse.scss +1 -1
- package/assets/styles/vendor/vue-select.scss +4 -3
- package/assets/translations/en-us.yaml +669 -73
- package/assets/translations/zh-hans.yaml +547 -165
- package/chart/monitoring/steps/uninstall-v1.vue +2 -2
- package/cloud-credential/azure.vue +23 -0
- package/cloud-credential/harvester.vue +25 -62
- package/cloud-credential/pnap.vue +80 -0
- package/components/.DS_Store +0 -0
- package/components/AdvancedSection.vue +9 -2
- package/components/Alert.vue +2 -2
- package/components/ButtonDropdown.vue +0 -2
- package/components/ButtonGroup.vue +1 -0
- package/components/CollapsibleCard.vue +0 -1
- package/components/CruResource.vue +41 -4
- package/components/DetailTop.vue +58 -3
- package/components/DisableAuthProviderModal.vue +106 -0
- package/{rancher-components/components/Utils/DraggableZone → components}/DraggableZone.vue +0 -0
- package/components/ExplorerMembers.vue +253 -30
- package/components/ExplorerProjectsNamespaces.vue +77 -33
- package/components/GrowlManager.vue +3 -3
- package/components/IconOrSvg.vue +149 -0
- package/components/LogItem.vue +69 -0
- package/components/PodSecurityAdmission.vue +302 -0
- package/components/PromptModal.vue +1 -0
- package/components/ResourceDetail/Masthead.vue +54 -2
- package/components/ResourceDetail/index.vue +12 -5
- package/components/ResourceList/Masthead.vue +11 -1
- package/components/ResourceList/ResourceLoadingIndicator.vue +12 -2
- package/components/ResourceList/index.vue +53 -12
- package/components/ResourceList/resource-list.config.js +7 -0
- package/components/ResourceTable.vue +31 -6
- package/components/SimpleBox.vue +1 -1
- package/components/SortableTable/THead.vue +15 -5
- package/components/SortableTable/index.vue +21 -10
- package/components/Tabbed/index.vue +20 -15
- package/components/__tests__/.DS_Store +0 -0
- package/components/__tests__/AsyncButton.test.ts +140 -0
- package/components/__tests__/BackLink.test.ts +33 -0
- package/components/__tests__/ButtonGroup.test.ts +124 -0
- package/components/__tests__/ClusterBadge.test.ts +32 -0
- package/components/__tests__/CollapsibleCard.test.ts +64 -0
- package/components/__tests__/ConsumptionGauge.test.ts +88 -0
- package/components/__tests__/CruResource.test.ts +3 -2
- package/components/__tests__/FixedBanner.test.ts +129 -0
- package/components/__tests__/GrowlManager.test.ts +147 -0
- package/components/__tests__/NamespaceFilter.test.ts +33 -25
- package/components/__tests__/PercentageBar.test.ts +32 -0
- package/components/__tests__/PodSecurityAdmission.test.ts +398 -0
- package/components/auth/AuthBanner.vue +20 -10
- package/components/auth/RoleDetailEdit.vue +26 -17
- package/components/auth/SelectPrincipal.vue +36 -5
- package/components/form/ArrayList.vue +3 -35
- package/components/form/ArrayListGrouped.vue +13 -4
- package/components/form/ArrayListSelect.vue +5 -5
- package/components/form/Error.vue +8 -0
- package/components/form/KeyValue.vue +39 -7
- package/components/form/LabeledSelect.vue +5 -2
- package/components/form/Labels.vue +46 -16
- package/components/form/Members/ClusterPermissionsEditor.vue +17 -17
- package/components/form/Members/MembershipEditor.vue +12 -12
- package/components/form/NameNsDescription.vue +1 -1
- package/components/form/NodeScheduling.vue +1 -1
- package/components/form/Probe.vue +3 -3
- package/components/form/ResourceQuota/Project.vue +6 -6
- package/components/form/ResourceTabs/index.vue +1 -6
- package/components/form/Security.vue +7 -6
- package/components/form/Select.vue +3 -2
- package/components/form/SelectOrCreateAuthSecret.vue +22 -29
- package/components/form/ServicePorts.vue +8 -0
- package/components/form/WorkloadPorts.vue +7 -1
- package/components/form/__tests__/ArrayList.test.ts +74 -0
- package/components/form/__tests__/ArrayListGrouped.test.ts +6 -4
- package/components/formatter/Checked.vue +1 -1
- package/components/formatter/ClusterLink.vue +5 -0
- package/components/formatter/IconIsDefault.vue +2 -2
- package/components/formatter/InternalExternalIP.vue +11 -8
- package/components/formatter/LiveDuration.vue +78 -0
- package/components/formatter/WorkloadHealthScale.vue +5 -3
- package/components/nav/Header.vue +6 -3
- package/components/nav/NamespaceFilter.vue +146 -63
- package/components/nav/TopLevelMenu.vue +22 -19
- package/components/nav/WindowManager/ContainerLogs.vue +83 -126
- package/components/nav/WindowManager/ContainerShell.vue +9 -7
- package/components/nav/WindowManager/Window.vue +2 -0
- package/components/nav/WindowManager/index.vue +10 -0
- package/config/elemental-types.js +9 -0
- package/config/features.js +2 -0
- package/config/home-links.js +4 -1
- package/config/pod-security-admission.ts +82 -0
- package/config/product/apps.js +1 -1
- package/config/product/auth.js +6 -5
- package/config/product/explorer.js +6 -6
- package/config/product/fleet.js +1 -1
- package/config/product/manager.js +6 -2
- package/config/secret.js +0 -1
- package/config/settings.ts +26 -9
- package/config/table-headers.js +22 -11
- package/config/types.js +4 -1
- package/content/docs/zh-hans/getting-started.md +113 -137
- package/content/docs/zh-hans/whats-new.md +8 -46
- package/creators/pkg/package-lock.json +37 -0
- package/creators/pkg/package.json +1 -1
- package/detail/catalog.cattle.io.app.vue +1 -1
- package/detail/pod.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +35 -9
- package/detail/service.vue +2 -9
- package/detail/workload/index.vue +0 -1
- package/dialog/AddClusterMemberDialog.vue +22 -28
- package/dialog/AddProjectMemberDialog.vue +53 -9
- package/dialog/DiagnosticTimingsDialog.vue +8 -7
- package/dialog/DrainNode.vue +44 -48
- package/dialog/ForceMachineRemoveDialog.vue +5 -7
- package/dialog/GenericPrompt.vue +15 -20
- package/dialog/RollbackWorkloadDialog.vue +15 -46
- package/dialog/RotateCertificatesDialog.vue +5 -7
- package/dialog/RotateEncryptionKeyDialog.vue +5 -9
- package/dialog/SaveAsRKETemplateDialog.vue +5 -13
- package/dialog/ScaleMachineDownDialog.vue +1 -1
- package/dialog/ScalePoolDownDialog.vue +121 -0
- package/edit/__tests__/management.cattle.io.setting.test.ts +3 -3
- package/edit/auth/azuread.vue +16 -16
- package/edit/auth/github.vue +8 -0
- package/edit/auth/googleoauth.vue +10 -1
- package/edit/auth/ldap/index.vue +10 -0
- package/edit/auth/oidc.vue +10 -0
- package/edit/auth/saml.vue +10 -0
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -1
- package/edit/cloudcredential.vue +3 -7
- package/edit/logging-flow/Match.vue +39 -8
- package/edit/logging-flow/index.vue +27 -4
- package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +107 -0
- package/edit/management.cattle.io.project.vue +8 -1
- package/edit/management.cattle.io.setting.vue +5 -2
- package/edit/management.cattle.io.user.vue +7 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +23 -7
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +2 -2
- package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +14 -6
- package/edit/namespace.vue +18 -4
- package/edit/networking.k8s.io.ingress/Certificate.vue +1 -0
- package/edit/networking.k8s.io.ingress/IngressClass.vue +8 -6
- package/edit/networking.k8s.io.ingress/RulePath.vue +12 -6
- package/edit/networking.k8s.io.ingress/index.vue +8 -6
- package/edit/persistentvolume/index.vue +30 -27
- package/edit/persistentvolume/plugins/cephfs.vue +29 -29
- package/edit/persistentvolume/plugins/csi.vue +102 -62
- package/edit/persistentvolume/plugins/fc.vue +19 -19
- package/edit/persistentvolume/plugins/iscsi.vue +45 -45
- package/edit/persistentvolume/plugins/rbd.vue +39 -39
- package/edit/persistentvolumeclaim.vue +78 -75
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -7
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +10 -1
- package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +87 -27
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -6
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +93 -0
- package/edit/provisioning.cattle.io.cluster/import.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/index.vue +29 -6
- package/edit/provisioning.cattle.io.cluster/rke2.vue +440 -152
- package/edit/secret/index.vue +3 -7
- package/edit/service.vue +3 -1
- package/edit/storage.k8s.io.storageclass/index.vue +100 -16
- package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +114 -0
- package/edit/workload/__tests__/index.test.ts +98 -0
- package/edit/workload/index.vue +58 -8
- package/edit/workload/mixins/workload.js +107 -70
- package/edit/workload/storage/ContainerMountPaths.vue +0 -10
- package/edit/workload/storage/emptyDir.vue +88 -0
- package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
- package/edit/workload/storage/index.vue +8 -0
- package/edit/workload/storage/persistentVolumeClaim/index.vue +1 -1
- package/layouts/default.vue +57 -44
- package/list/__tests__/workload.test.ts +5 -2
- package/list/catalog.cattle.io.app.vue +1 -0
- package/list/cis.cattle.io.clusterscan.vue +1 -0
- package/list/fleet.cattle.io.bundle.vue +5 -6
- package/list/fleet.cattle.io.cluster.vue +6 -3
- package/list/fleet.cattle.io.clusterregistrationtoken.vue +5 -6
- package/list/fleet.cattle.io.gitrepo.vue +4 -9
- package/list/helm.cattle.io.projecthelmchart.vue +1 -5
- package/list/logging.banzaicloud.io.clusterflow.vue +4 -1
- package/list/logging.banzaicloud.io.flow.vue +6 -5
- package/list/management.cattle.io.cluster.vue +1 -0
- package/list/management.cattle.io.feature.vue +3 -4
- package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +47 -0
- package/list/management.cattle.io.setting.vue +2 -2
- package/list/management.cattle.io.user.vue +4 -10
- package/list/monitoring.coreos.com.alertmanagerconfig.vue +2 -7
- package/list/node.vue +8 -5
- package/list/persistentvolume.vue +3 -3
- package/list/persistentvolumeclaim.vue +3 -4
- package/list/provisioning.cattle.io.cluster.vue +18 -19
- package/list/service.vue +6 -14
- package/list/workload.vue +43 -38
- package/machine-config/azure.vue +429 -60
- package/machine-config/pnap.vue +288 -0
- package/mixins/auth-config.js +1 -3
- package/mixins/browser-tab-visibility.js +8 -14
- package/mixins/chart.js +1 -1
- package/mixins/create-edit-view/impl.js +4 -0
- package/mixins/create-edit-view/index.js +4 -2
- package/mixins/resource-fetch-namespaced.js +98 -0
- package/mixins/resource-fetch.js +79 -45
- package/mixins/resource-manager.js +1 -23
- package/models/apps.controllerrevision.js +7 -0
- package/models/apps.daemonset.js +18 -0
- package/models/apps.deployment.js +44 -0
- package/models/apps.replicaset.js +7 -0
- package/models/apps.statefulset.js +18 -0
- package/models/batch.job.js +7 -14
- package/models/cluster/node.js +10 -2
- package/models/cluster.x-k8s.io.machine.js +26 -4
- package/models/cluster.x-k8s.io.machinedeployment.js +12 -2
- package/models/event.js +7 -0
- package/models/logging.banzaicloud.io.flow.js +4 -0
- package/models/management.cattle.io.cluster.js +1 -1
- package/models/management.cattle.io.clusterroletemplatebinding.js +1 -1
- package/models/management.cattle.io.globalrole.js +2 -2
- package/models/management.cattle.io.node.js +37 -2
- package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +4 -0
- package/models/management.cattle.io.project.js +30 -11
- package/models/management.cattle.io.setting.js +1 -1
- package/models/management.cattle.io.user.js +37 -1
- package/models/namespace.js +42 -5
- package/models/persistentvolume.js +14 -2
- package/models/pod.js +15 -0
- package/models/projectroletemplatebinding.js +7 -0
- package/models/provisioning.cattle.io.cluster.js +61 -10
- package/models/rke-machine.cattle.io.pnapmachinetemplate.js +15 -0
- package/models/service.js +14 -13
- package/models/storage.k8s.io.storageclass.js +33 -18
- package/models/workload.js +38 -7
- package/nuxt.config.js +27 -17
- package/package.json +7 -7
- package/pages/about.vue +14 -2
- package/pages/c/_cluster/apps/charts/index.vue +4 -3
- package/pages/c/_cluster/apps/charts/install.vue +59 -22
- package/pages/c/_cluster/auth/config/_id.vue +6 -0
- package/pages/c/_cluster/auth/config/index.vue +8 -6
- package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
- package/pages/c/_cluster/auth/roles/index.vue +1 -1
- package/pages/c/_cluster/explorer/index.vue +12 -6
- package/pages/c/_cluster/longhorn/index.vue +1 -1
- package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +15 -4
- package/pages/c/_cluster/monitoring/index.vue +1 -1
- package/pages/c/_cluster/neuvector/index.vue +1 -1
- package/pages/c/_cluster/settings/performance.vue +48 -2
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +34 -1
- package/pages/c/_cluster/uiplugins/index.vue +28 -2
- package/pages/diagnostic.vue +5 -4
- package/pages/home.vue +105 -30
- package/pages/prefs.vue +23 -12
- package/pages/rio/mesh.vue +1 -1
- package/pkg/dynamic-importer.lib.js +8 -0
- package/pkg/vue.config.js +4 -0
- package/plugins/dashboard-store/__tests__/mutations.spec.js +406 -0
- package/plugins/dashboard-store/actions.js +32 -25
- package/plugins/dashboard-store/getters.js +50 -33
- package/plugins/dashboard-store/mutations.js +134 -28
- package/plugins/dashboard-store/resource-class.js +21 -41
- package/plugins/steve/actions.js +30 -0
- package/plugins/steve/caches/resourceCache.js +60 -0
- package/plugins/steve/getters.js +44 -1
- package/plugins/steve/mutations.js +97 -36
- package/plugins/steve/resourceWatcher.js +277 -0
- package/plugins/steve/schema.utils.js +25 -0
- package/plugins/steve/subscribe.js +288 -115
- package/plugins/steve/worker/index.js +17 -0
- package/plugins/steve/worker/web-worker.advanced.js +302 -0
- package/plugins/steve/{web-worker.steve-sub-worker.js → worker/web-worker.basic.js} +3 -44
- package/rancher-components/Card/Card.vue +3 -3
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +1 -0
- package/rancher-components/StringList/StringList.test.ts +45 -420
- package/rancher-components/StringList/StringList.vue +1 -10
- package/rancher-components/components/Banner/Banner.test.ts +44 -0
- package/rancher-components/components/Banner/Banner.vue +129 -61
- package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +13 -22
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +8 -6
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +9 -9
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -1
- package/rancher-components/components/StringList/StringList.test.ts +7 -7
- package/rancher-components/components/StringList/StringList.vue +21 -15
- package/scripts/test-plugins-build.sh +8 -0
- package/static/loading-indicator.html +1 -1
- package/store/index.js +54 -3
- package/store/plugins.js +0 -17
- package/store/pnap.js +128 -0
- package/store/prefs.js +4 -2
- package/store/type-map.js +55 -13
- package/types/pod-security-admission.ts +36 -0
- package/types/shell/index.d.ts +496 -396
- package/utils/__tests__/object.test.ts +17 -1
- package/utils/__tests__/pod-security-admission.test.ts +61 -0
- package/utils/async.ts +36 -0
- package/utils/color.js +45 -0
- package/utils/crypto/browserHashUtils.js +18 -0
- package/utils/dynamic-importer.js +8 -0
- package/utils/install-redirect.js +1 -1
- package/utils/object.js +24 -0
- package/utils/pod-security-admission.ts +39 -0
- package/utils/socket.js +61 -24
- package/utils/string.js +2 -0
- package/utils/svg-filter.js +301 -0
- package/utils/time.js +49 -0
- package/utils/validators/cidr.js +4 -0
- package/utils/validators/formRules/__tests__/index.test.ts +23 -3
- package/utils/validators/formRules/index.ts +14 -0
- package/config/product/harvester-manager.js +0 -162
- package/edit/harvesterhci.io.management.cluster.vue +0 -153
- package/list/harvesterhci.io.management.cluster.vue +0 -241
- package/machine-config/harvester.vue +0 -693
- package/models/harvesterhci.io.management.cluster.js +0 -228
- package/pages/c/_cluster/harvesterManager/index.vue +0 -24
- package/rancher-components/Card/Card.test.ts +0 -39
- package/rancher-components/Utils/DraggableZone/DraggableZone.vue +0 -181
- package/rancher-components/Utils/DraggableZone/index.ts +0 -1
- package/rancher-components/components/Utils/DraggableZone/index.ts +0 -1
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced Worker is enabled by performance setting
|
|
3
|
+
* relocates cluster resource sockets off the UI thread and into a webworker
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { SCHEMA, COUNT } from '@shell/config/types';
|
|
7
|
+
import ResourceWatcher, { watchKeyFromMessage } from '@shell/plugins/steve/resourceWatcher';
|
|
8
|
+
import ResourceCache from '@shell/plugins/steve/caches/resourceCache';
|
|
9
|
+
import { EVENT_MESSAGE, EVENT_CONNECT_ERROR, EVENT_DISCONNECT_ERROR } from '@shell/utils/socket';
|
|
10
|
+
import { normalizeType, keyFieldFor } from '@shell/plugins/dashboard-store/normalize';
|
|
11
|
+
import { addSchemaIndexFields } from '@shell/plugins/steve/schema.utils';
|
|
12
|
+
|
|
13
|
+
const caches = {};
|
|
14
|
+
|
|
15
|
+
const state = {
|
|
16
|
+
watcher: undefined,
|
|
17
|
+
store: '', // Store name
|
|
18
|
+
/**
|
|
19
|
+
* Store `watch`/`unwatch` events to process when the socket is created
|
|
20
|
+
*/
|
|
21
|
+
workerQueue: [],
|
|
22
|
+
batchChanges: {},
|
|
23
|
+
debugWorker: false
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const trace = (...args) => {
|
|
27
|
+
state.debugWorker && console.info('Advanced Worker:', ...args); // eslint-disable-line no-console
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
trace('created');
|
|
31
|
+
|
|
32
|
+
const maintenanceInterval = setInterval(() => {
|
|
33
|
+
if (Object.keys(state.batchChanges).length) {
|
|
34
|
+
self.postMessage({ batchChanges: state.batchChanges });
|
|
35
|
+
state.batchChanges = {};
|
|
36
|
+
}
|
|
37
|
+
}, 5000); // 5 seconds
|
|
38
|
+
|
|
39
|
+
const makeResourceProps = (msg) => {
|
|
40
|
+
const { resourceType, data: { type }, data } = msg;
|
|
41
|
+
const rawType = resourceType || type;
|
|
42
|
+
const normalizedType = normalizeType(rawType === 'counts' ? COUNT : rawType);
|
|
43
|
+
const keyField = keyFieldFor(normalizedType);
|
|
44
|
+
|
|
45
|
+
if ( normalizedType === SCHEMA ) {
|
|
46
|
+
addSchemaIndexFields(data);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
type: normalizedType,
|
|
51
|
+
id: data[keyField],
|
|
52
|
+
data
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Pass the EVENT_CONNECT_ERROR / EVENT_DISCONNECT_ERROR back to the UI thread
|
|
58
|
+
*/
|
|
59
|
+
const handleConnectionError = (eventType, event, watcher) => {
|
|
60
|
+
trace('createWatcher', eventType, event);
|
|
61
|
+
self.postMessage({
|
|
62
|
+
[eventType]: {
|
|
63
|
+
type: event.type,
|
|
64
|
+
detail: event.detail,
|
|
65
|
+
srcElement: {
|
|
66
|
+
disconnectedAt: watcher.disconnectedAt,
|
|
67
|
+
url: watcher.url,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Remove any pending messages related to this resource from the queue
|
|
75
|
+
*/
|
|
76
|
+
const removeFromWorkerQueue = (watchKey) => {
|
|
77
|
+
state.workerQueue = state.workerQueue.filter((workerMessage) => {
|
|
78
|
+
const [, msg] = Object.entries(workerMessage)[0];
|
|
79
|
+
const workerMessageWatchKey = watchKeyFromMessage(msg);
|
|
80
|
+
|
|
81
|
+
return watchKey !== workerMessageWatchKey;
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* These are things that we do when we get a message from the UI thread
|
|
87
|
+
*/
|
|
88
|
+
const workerActions = {
|
|
89
|
+
// ToDo: SM we'll make a generic loader for all resource types when we need it but it'll be pretty similar to this
|
|
90
|
+
loadSchemas: (collection) => {
|
|
91
|
+
if (!caches[SCHEMA]) {
|
|
92
|
+
caches[SCHEMA] = new ResourceCache(SCHEMA);
|
|
93
|
+
}
|
|
94
|
+
caches[SCHEMA].load(collection);
|
|
95
|
+
},
|
|
96
|
+
createWatcher: (metadata) => {
|
|
97
|
+
trace('createWatcher', metadata);
|
|
98
|
+
|
|
99
|
+
const {
|
|
100
|
+
connectionMetadata, maxTries, url, csrf
|
|
101
|
+
} = metadata;
|
|
102
|
+
|
|
103
|
+
if (!state.watcher) {
|
|
104
|
+
state.watcher = new ResourceWatcher(url, true, null, null, maxTries, csrf);
|
|
105
|
+
|
|
106
|
+
state.watcher.addEventListener(EVENT_MESSAGE, (e) => {
|
|
107
|
+
const event = e.detail;
|
|
108
|
+
|
|
109
|
+
if (event.data) {
|
|
110
|
+
const msg = JSON.parse(event.data);
|
|
111
|
+
|
|
112
|
+
if (msg.name) {
|
|
113
|
+
if (resourceWatcherActions[msg.name]) {
|
|
114
|
+
resourceWatcherActions[msg.name](msg);
|
|
115
|
+
} else {
|
|
116
|
+
resourceWatcherActions.dispatch(msg);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
state.watcher.addEventListener(EVENT_CONNECT_ERROR, (e) => {
|
|
123
|
+
handleConnectionError(EVENT_CONNECT_ERROR, e, state.watcher);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
state.watcher.addEventListener(EVENT_DISCONNECT_ERROR, (e) => {
|
|
127
|
+
handleConnectionError(EVENT_DISCONNECT_ERROR, e, state.watcher);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
state.watcher.setDebug(state.debugWorker);
|
|
131
|
+
|
|
132
|
+
state.watcher.connect(connectionMetadata);
|
|
133
|
+
|
|
134
|
+
// Flush the workerQueue
|
|
135
|
+
while (state.workerQueue.length > 0) {
|
|
136
|
+
trace('createWatcher', 'flushing workerQueue', state.workerQueue);
|
|
137
|
+
|
|
138
|
+
const workerMessage = state.workerQueue.shift();
|
|
139
|
+
const [action, msg] = Object.entries(workerMessage)[0];
|
|
140
|
+
|
|
141
|
+
if (workerActions[action]) {
|
|
142
|
+
workerActions[action](msg);
|
|
143
|
+
} else {
|
|
144
|
+
console.warn('no associated action for:', action); // eslint-disable-line no-console
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
watch: (msg) => {
|
|
150
|
+
trace('watch', msg);
|
|
151
|
+
|
|
152
|
+
const watchKey = watchKeyFromMessage(msg);
|
|
153
|
+
|
|
154
|
+
if (msg.stop) {
|
|
155
|
+
workerActions.unwatch(watchKey);
|
|
156
|
+
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// If socket is in error don't try to watch.... unless we `force` it
|
|
161
|
+
if (!msg.force && !!state.watcher?.watches[watchKey]?.error) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (!state.watcher) {
|
|
166
|
+
state.workerQueue.push({ watch: msg });
|
|
167
|
+
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const {
|
|
172
|
+
resourceType,
|
|
173
|
+
namespace,
|
|
174
|
+
id,
|
|
175
|
+
selector,
|
|
176
|
+
resourceVersion
|
|
177
|
+
} = msg;
|
|
178
|
+
|
|
179
|
+
const resourceVersionTime = resourceVersion ? Date.now() : undefined;
|
|
180
|
+
const skipResourceVersion = [SCHEMA, COUNT].includes(resourceType);
|
|
181
|
+
|
|
182
|
+
const watchObject = {
|
|
183
|
+
resourceType,
|
|
184
|
+
id,
|
|
185
|
+
namespace,
|
|
186
|
+
selector
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
state.watcher.watch(watchKey, resourceVersion, resourceVersionTime, watchObject, skipResourceVersion);
|
|
190
|
+
},
|
|
191
|
+
unwatch: (watchKey) => {
|
|
192
|
+
trace('unwatch', watchKey);
|
|
193
|
+
|
|
194
|
+
removeFromWorkerQueue(watchKey);
|
|
195
|
+
|
|
196
|
+
if (!state.watcher) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
state.watcher.unwatch(watchKey);
|
|
201
|
+
},
|
|
202
|
+
initWorker: ({ storeName }) => {
|
|
203
|
+
trace('initWorker', storeName);
|
|
204
|
+
|
|
205
|
+
state.store = storeName;
|
|
206
|
+
},
|
|
207
|
+
destroyWorker: () => {
|
|
208
|
+
trace('destroyWorker');
|
|
209
|
+
|
|
210
|
+
clearInterval(maintenanceInterval);
|
|
211
|
+
|
|
212
|
+
function destroyWorkerComplete() {
|
|
213
|
+
delete self.onmessage;
|
|
214
|
+
self.postMessage({ destroyWorker: true }); // we're only passing the boolean here because the key needs to be something truthy to ensure it's passed on the object.
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// disconnect takes a callback which we'll use to close the webworker
|
|
218
|
+
if (state.watcher) {
|
|
219
|
+
state.watcher?.disconnect().then(destroyWorkerComplete);
|
|
220
|
+
} else {
|
|
221
|
+
destroyWorkerComplete();
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
toggleDebug: ({ on }) => {
|
|
226
|
+
state.debugWorker = !!on;
|
|
227
|
+
state.watcher.setDebug(!!on);
|
|
228
|
+
},
|
|
229
|
+
updateBatch(type, id, change) {
|
|
230
|
+
if (!state.batchChanges[type]) {
|
|
231
|
+
state.batchChanges[type] = {};
|
|
232
|
+
}
|
|
233
|
+
state.batchChanges[type][id] = change;
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* These are things that we do when we get a message from the resourceWatcher
|
|
239
|
+
*/
|
|
240
|
+
const resourceWatcherActions = {
|
|
241
|
+
'resource.change': (msg) => {
|
|
242
|
+
const { type, id, data } = makeResourceProps(msg);
|
|
243
|
+
|
|
244
|
+
if (caches[type]) {
|
|
245
|
+
caches[type].change(data, () => workerActions.updateBatch(type, id, data));
|
|
246
|
+
} else {
|
|
247
|
+
workerActions.updateBatch(type, id, data);
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
// ToDo: SM create is functionally identical to change in the cache but the worker isn't supposed to know that hence the near-duplicate code
|
|
251
|
+
'resource.create': (msg) => {
|
|
252
|
+
const { type, id, data } = makeResourceProps(msg);
|
|
253
|
+
|
|
254
|
+
if (caches[type]) {
|
|
255
|
+
caches[type].create(data, () => workerActions.updateBatch(type, id, data));
|
|
256
|
+
} else {
|
|
257
|
+
workerActions.updateBatch(type, id, data);
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
'resource.start': (msg) => {
|
|
261
|
+
// State is handled in the resourceWatcher, no need to bubble out to UI thread
|
|
262
|
+
},
|
|
263
|
+
'resource.remove': (msg) => {
|
|
264
|
+
const { type, id } = makeResourceProps(msg);
|
|
265
|
+
|
|
266
|
+
if (caches[type]) {
|
|
267
|
+
caches[type].remove(id, () => workerActions.updateBatch(type, id, {}));
|
|
268
|
+
} else {
|
|
269
|
+
workerActions.updateBatch(type, id, {});
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
'resource.stop': (msg) => {
|
|
273
|
+
// State is handled in the resourceWatcher, no need to bubble out to UI thread
|
|
274
|
+
const watchKey = watchKeyFromMessage(msg);
|
|
275
|
+
|
|
276
|
+
removeFromWorkerQueue(watchKey);
|
|
277
|
+
},
|
|
278
|
+
'resource.error': (msg) => {
|
|
279
|
+
// State is handled in the resourceWatcher, no need to bubble out to UI thread
|
|
280
|
+
console.warn(`Resource error [${ state.store }]`, msg.resourceType, ':', msg.data.error); // eslint-disable-line no-console
|
|
281
|
+
},
|
|
282
|
+
dispatch: (msg) => {
|
|
283
|
+
self.postMessage({ dispatch: msg });
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Covers message from UI Thread to Worker
|
|
289
|
+
*/
|
|
290
|
+
onmessage = (e) => {
|
|
291
|
+
/* on the off chance there's more than key in the message, we handle them in the order that they "keys" method provides which is
|
|
292
|
+
// good enough for now considering that we never send more than one message action at a time right now */
|
|
293
|
+
const messageActions = Object.keys(e?.data);
|
|
294
|
+
|
|
295
|
+
messageActions.forEach((action) => {
|
|
296
|
+
if (workerActions[action]) {
|
|
297
|
+
workerActions[action](e?.data[action]);
|
|
298
|
+
} else {
|
|
299
|
+
console.warn('no associated action for:', action); // eslint-disable-line no-console
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}; // bind everything to the worker's onmessage handler via the workerActions
|
|
@@ -1,36 +1,16 @@
|
|
|
1
1
|
import { SCHEMA } from '@shell/config/types';
|
|
2
|
+
import { hashObj } from '@shell/utils/crypto/browserHashUtils';
|
|
3
|
+
import { removeSchemaIndexFields } from '@shell/plugins/steve/schema.utils';
|
|
2
4
|
|
|
3
|
-
const COUNTS_FLUSH_TIMEOUT = 5000;
|
|
4
5
|
const SCHEMA_FLUSH_TIMEOUT = 2500;
|
|
5
6
|
|
|
6
7
|
const state = {
|
|
7
8
|
store: '', // Store name
|
|
8
|
-
counts: [], // Buffer of count resources recieved in a given window
|
|
9
|
-
countTimer: undefined, // Tiemr to flush the count buffer
|
|
10
9
|
flushTimer: undefined, // Timer to flush the schema chaneg queue
|
|
11
10
|
queue: [], // Schema change queue
|
|
12
11
|
schemas: {} // Map of schema id to hash to track when a schema actually changes
|
|
13
12
|
};
|
|
14
13
|
|
|
15
|
-
// Quick, simple hash function
|
|
16
|
-
function hash(str) {
|
|
17
|
-
let hash = 0;
|
|
18
|
-
|
|
19
|
-
for (let i = 0; i < str.length; i++) {
|
|
20
|
-
const char = str.charCodeAt(i);
|
|
21
|
-
|
|
22
|
-
hash = (hash << 5) - hash + char;
|
|
23
|
-
hash &= hash;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return new Uint32Array([hash])[0].toString(36);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Quick, simple hash function to generate hash for an object
|
|
30
|
-
function hashObj(obj) {
|
|
31
|
-
return hash(JSON.stringify(obj, null, 2));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
14
|
function flush() {
|
|
35
15
|
state.queue.forEach((schema) => {
|
|
36
16
|
const hash = hashObj(schema);
|
|
@@ -81,29 +61,9 @@ const workerActions = {
|
|
|
81
61
|
},
|
|
82
62
|
|
|
83
63
|
destroyWorker: () => {
|
|
84
|
-
clearTimeout(state.countTimer);
|
|
85
64
|
clearTimeout(state.flushTimer);
|
|
86
65
|
|
|
87
66
|
self.postMessage({ destroyWorker: true }); // we're only passing the boolean here because the key needs to be something truthy to ensure it's passed on the object.
|
|
88
|
-
|
|
89
|
-
// Web worker global function to terminate the web worker
|
|
90
|
-
close();
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
// Debounce counts messages so we only process at most 1 every 5 seconds
|
|
94
|
-
countsUpdate(resource) {
|
|
95
|
-
state.counts.push(resource);
|
|
96
|
-
|
|
97
|
-
if (!state.countTimer) {
|
|
98
|
-
state.countTimer = setTimeout(() => {
|
|
99
|
-
const last = state.counts.pop();
|
|
100
|
-
|
|
101
|
-
state.counts = [];
|
|
102
|
-
state.countTimer = null;
|
|
103
|
-
|
|
104
|
-
load(last);
|
|
105
|
-
}, COUNTS_FLUSH_TIMEOUT);
|
|
106
|
-
}
|
|
107
67
|
},
|
|
108
68
|
|
|
109
69
|
// Called to load schema
|
|
@@ -111,8 +71,7 @@ const workerActions = {
|
|
|
111
71
|
schemas.forEach((schema) => {
|
|
112
72
|
// These properties are added to the object, but aren't on the raw object, so remove them
|
|
113
73
|
// otherwise our comparison will show changes when there aren't any
|
|
114
|
-
|
|
115
|
-
delete schema._group;
|
|
74
|
+
removeSchemaIndexFields(schema);
|
|
116
75
|
|
|
117
76
|
state.schemas[schema.id] = hashObj(schema);
|
|
118
77
|
});
|
|
@@ -57,18 +57,18 @@ export default Vue.extend({
|
|
|
57
57
|
<template>
|
|
58
58
|
<div class="card-container" :class="{'highlight-border': showHighlightBorder, 'card-sticky': sticky}">
|
|
59
59
|
<div class="card-wrap">
|
|
60
|
-
<div class="card-title"
|
|
60
|
+
<div class="card-title">
|
|
61
61
|
<slot name="title">
|
|
62
62
|
{{ title }}
|
|
63
63
|
</slot>
|
|
64
64
|
</div>
|
|
65
65
|
<hr />
|
|
66
|
-
<div class="card-body"
|
|
66
|
+
<div class="card-body">
|
|
67
67
|
<slot name="body">
|
|
68
68
|
{{ content }}
|
|
69
69
|
</slot>
|
|
70
70
|
</div>
|
|
71
|
-
<div v-if="showActions" class="card-actions"
|
|
71
|
+
<div v-if="showActions" class="card-actions">
|
|
72
72
|
<slot name="actions">
|
|
73
73
|
<button class="btn role-primary" @click="buttonAction">
|
|
74
74
|
{{ buttonText }}
|