@rancher/shell 3.0.1 → 3.0.2-rc.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/base/_basic.scss +17 -5
- package/assets/styles/base/_mixins.scss +2 -1
- package/assets/styles/global/_button.scss +10 -0
- package/assets/styles/global/_form.scss +2 -2
- package/assets/translations/en-us.yaml +33 -5
- package/assets/translations/zh-hans.yaml +1 -1
- package/components/ActionMenu.vue +8 -0
- package/components/AsyncButton.vue +9 -3
- package/components/BannerGraphic.vue +10 -0
- package/components/ButtonGroup.vue +2 -0
- package/components/ButtonMultiAction.vue +6 -0
- package/components/ClusterIconMenu.vue +1 -1
- package/components/CodeMirror.vue +28 -1
- package/components/CommunityLinks.vue +13 -0
- package/components/CruResource.vue +6 -0
- package/components/GrowlManager.vue +14 -4
- package/components/LocaleSelector.vue +49 -5
- package/components/PaginatedResourceTable.vue +4 -3
- package/components/ResourceDetail/Masthead.vue +11 -4
- package/components/ResourceList/index.vue +5 -3
- package/components/ResourceTable.vue +1 -1
- package/components/SortableTable/THead.vue +19 -4
- package/components/SortableTable/index.vue +13 -9
- package/components/SortableTable/selection.js +19 -5
- package/components/YamlEditor.vue +2 -1
- package/components/auth/SelectPrincipal.vue +1 -1
- package/components/fleet/FleetBundles.vue +2 -1
- package/components/form/LabeledSelect.vue +20 -7
- package/components/form/NodeScheduling.vue +5 -1
- package/components/form/Password.vue +23 -13
- package/components/form/ResourceLabeledSelect.vue +1 -1
- package/components/form/Select.vue +28 -6
- package/components/form/SelectOrCreateAuthSecret.vue +39 -11
- package/components/form/__tests__/NodeScheduling.test.ts +44 -0
- package/components/formatter/Endpoints.vue +1 -1
- package/components/formatter/LiveExpiryDate.vue +5 -1
- package/components/formatter/ServiceTargets.vue +1 -1
- package/components/formatter/ServiceType.vue +19 -17
- package/components/nav/Pinned.vue +6 -1
- package/components/nav/TopLevelMenu.helper.ts +17 -1
- package/components/nav/TopLevelMenu.vue +154 -19
- package/config/pagination-table-headers.js +9 -1
- package/config/product/apps.js +63 -30
- package/config/product/explorer.js +182 -17
- package/config/product/settings.js +9 -1
- package/config/router/routes.js +0 -1
- package/config/settings.ts +20 -2
- package/config/table-headers.js +23 -15
- package/config/types.js +2 -1
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +12 -3
- package/edit/fleet.cattle.io.gitrepo.vue +40 -33
- package/edit/provisioning.cattle.io.cluster/rke2.vue +13 -2
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +10 -2
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +8 -2
- package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +6 -3
- package/edit/workload/mixins/workload.js +15 -7
- package/list/catalog.cattle.io.app.vue +4 -11
- package/list/catalog.cattle.io.clusterrepo.vue +59 -25
- package/list/fleet.cattle.io.bundle.vue +2 -2
- package/list/management.cattle.io.feature.vue +12 -5
- package/list/management.cattle.io.setting.vue +30 -19
- package/list/namespace.vue +4 -1
- package/list/networking.k8s.io.ingress.vue +14 -11
- package/list/node.vue +65 -63
- package/list/persistentvolume.vue +55 -20
- package/list/persistentvolumeclaim.vue +3 -15
- package/list/service.vue +16 -21
- package/list/workload.vue +35 -49
- package/mixins/resource-fetch.js +8 -1
- package/mixins/vue-select-overrides.js +10 -16
- package/models/management.cattle.io.cluster.js +6 -1
- package/models/persistentvolume.js +1 -3
- package/models/storage.k8s.io.storageclass.js +4 -0
- package/package.json +28 -29
- package/pages/c/_cluster/explorer/EventsTable.vue +58 -16
- package/pages/c/_cluster/explorer/index.vue +3 -16
- package/pages/c/_cluster/settings/performance.vue +49 -23
- package/pages/home.vue +24 -3
- package/pages/support/index.vue +1 -1
- package/plugins/floating-vue.js +1 -1
- package/plugins/steve/steve-pagination-utils.ts +85 -15
- package/rancher-components/Banner/Banner.vue +12 -0
- package/rancher-components/Form/Checkbox/Checkbox.vue +27 -5
- package/rancher-components/Form/Radio/RadioButton.vue +0 -6
- package/rancher-components/Form/Radio/RadioGroup.vue +5 -1
- package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +2 -2
- package/scripts/test-plugins-build.sh +21 -6
- package/scripts/typegen.sh +1 -0
- package/store/index.js +16 -0
- package/store/type-map.utils.ts +14 -1
- package/types/shell/index.d.ts +467 -418
- package/types/store/vuex.d.ts +1 -1
- package/types/vue-shim.d.ts +2 -8
- package/utils/cluster.js +2 -2
- package/utils/string.js +6 -0
- package/vue.config.js +3 -4
|
@@ -62,12 +62,24 @@ INPUT,
|
|
|
62
62
|
SELECT,
|
|
63
63
|
TEXTAREA,
|
|
64
64
|
.labeled-input,
|
|
65
|
-
.
|
|
66
|
-
.unlabeled-select,
|
|
67
|
-
.checkbox-custom,
|
|
68
|
-
.radio-custom {
|
|
65
|
+
.checkbox-custom {
|
|
69
66
|
&:focus, &.focused {
|
|
70
|
-
@include form-focus
|
|
67
|
+
@include form-focus;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.radio-custom,
|
|
72
|
+
.labeled-select,
|
|
73
|
+
.unlabeled-select {
|
|
74
|
+
&:focus-visible, &.focused {
|
|
75
|
+
@include focus-outline;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.labeled-select,
|
|
80
|
+
.unlabeled-select {
|
|
81
|
+
&.focused {
|
|
82
|
+
border-color: var(--outline);
|
|
71
83
|
}
|
|
72
84
|
}
|
|
73
85
|
|
|
@@ -158,5 +158,6 @@
|
|
|
158
158
|
|
|
159
159
|
@mixin focus-outline {
|
|
160
160
|
// Focus for form like elements (not to be confused with basic :focus style)
|
|
161
|
+
// we need to use !important because it needs to superseed other classes that might impact outlines
|
|
161
162
|
outline: 2px solid var(--primary-keyboard-focus);
|
|
162
|
-
}
|
|
163
|
+
}
|
|
@@ -106,6 +106,11 @@ button,
|
|
|
106
106
|
border: 0;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
&:focus-visible {
|
|
111
|
+
@include focus-outline;
|
|
112
|
+
outline-offset: 2px;
|
|
113
|
+
}
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
.role-tertiary {
|
|
@@ -180,6 +185,11 @@ fieldset[disabled] .btn {
|
|
|
180
185
|
z-index: 1;
|
|
181
186
|
}
|
|
182
187
|
|
|
188
|
+
&:focus-visible {
|
|
189
|
+
z-index: 1;
|
|
190
|
+
@include focus-outline;
|
|
191
|
+
}
|
|
192
|
+
|
|
183
193
|
&.active {
|
|
184
194
|
@extend .bg-primary;
|
|
185
195
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
generic:
|
|
5
5
|
add: Add
|
|
6
6
|
all: All
|
|
7
|
+
ascending: ascending
|
|
7
8
|
and: ' and '
|
|
8
9
|
back: Back
|
|
9
10
|
cancel: Cancel
|
|
@@ -19,6 +20,7 @@ generic:
|
|
|
19
20
|
customize: Customize
|
|
20
21
|
dashboard: Dashboard
|
|
21
22
|
default: Default
|
|
23
|
+
descending: descending
|
|
22
24
|
disabled: Disabled
|
|
23
25
|
done: Done
|
|
24
26
|
enabled: Enabled
|
|
@@ -115,11 +117,26 @@ generic:
|
|
|
115
117
|
basic: Basic
|
|
116
118
|
|
|
117
119
|
locale:
|
|
120
|
+
menu: Locale selector menu
|
|
118
121
|
en-us: English
|
|
119
122
|
zh-hans: 简体中文
|
|
120
123
|
none: (None)
|
|
121
124
|
|
|
122
125
|
nav:
|
|
126
|
+
ariaLabel:
|
|
127
|
+
topLevelMenu: Main menu
|
|
128
|
+
homePage: Home page navigation menu
|
|
129
|
+
cluster: Cluster menu item
|
|
130
|
+
harvesterCluster: Harvester cluster menu item
|
|
131
|
+
seeAll: See all clusters menu item
|
|
132
|
+
multiClusterApps: Main menu multi cluster app menu item
|
|
133
|
+
configurationApps: Main menu configuration app menu item
|
|
134
|
+
support: Support page link
|
|
135
|
+
about: About page link
|
|
136
|
+
pinCluster: Pin/Unpin cluster
|
|
137
|
+
alt:
|
|
138
|
+
mainMenuIcon: Main menu icon
|
|
139
|
+
mainMenuRancherLogo: Main menu Rancher logo
|
|
123
140
|
expandCollapseAppBar: Expand/Collapse the Application Bar
|
|
124
141
|
harvesterDashboard: Harvester Dashboard
|
|
125
142
|
backToRancher: Cluster Manager
|
|
@@ -196,6 +213,7 @@ nav:
|
|
|
196
213
|
placeholder: Filter clusters by...
|
|
197
214
|
noResults: No matching clusters
|
|
198
215
|
clusters: clusters
|
|
216
|
+
ariaLabel: Filter clusters on main menu
|
|
199
217
|
resourceSearch:
|
|
200
218
|
label: Resource Search
|
|
201
219
|
toolTip: Resource Search {key}
|
|
@@ -5169,11 +5187,14 @@ selectOrCreateAuthSecret:
|
|
|
5169
5187
|
basic:
|
|
5170
5188
|
username: Username
|
|
5171
5189
|
password: Password
|
|
5190
|
+
rke:
|
|
5191
|
+
info: "An RKE Auth Config secret contains the username and password concatenated and base64 encoded into the secret's 'auth' key"
|
|
5172
5192
|
namespaceGroup: "Namespace: {name}"
|
|
5173
5193
|
chooseExisting: "Choose an existing secret:"
|
|
5174
|
-
createSsh: Create
|
|
5175
|
-
createBasic: Create
|
|
5176
|
-
createS3: Create
|
|
5194
|
+
createSsh: Create an SSH Key Secret
|
|
5195
|
+
createBasic: Create an HTTP Basic Auth Secret
|
|
5196
|
+
createS3: Create an S3-Compatible Auth Secret
|
|
5197
|
+
createRKE: Create an RKE Auth Config Secret
|
|
5177
5198
|
|
|
5178
5199
|
serviceAccount:
|
|
5179
5200
|
automount: Automount Service Account Token
|
|
@@ -5743,6 +5764,7 @@ tableHeaders:
|
|
|
5743
5764
|
lastSchedule: Last Schedule
|
|
5744
5765
|
lastSeen: Last Seen
|
|
5745
5766
|
lastSeenTooltip: The time at which the most recent occurrence of this event was recorded
|
|
5767
|
+
lastUsed: Last Used
|
|
5746
5768
|
loggingOutputProviders: Provider
|
|
5747
5769
|
machines: Machines
|
|
5748
5770
|
machineNodeName: Node
|
|
@@ -5818,6 +5840,7 @@ tableHeaders:
|
|
|
5818
5840
|
resourcesReady: Resources Ready
|
|
5819
5841
|
restarts: Restarts
|
|
5820
5842
|
restart: Restart Required
|
|
5843
|
+
restartSystem: Restart { vendor }
|
|
5821
5844
|
restore: Restore
|
|
5822
5845
|
role: Role
|
|
5823
5846
|
roles: Roles
|
|
@@ -7409,6 +7432,8 @@ registryConfig:
|
|
|
7409
7432
|
##############################
|
|
7410
7433
|
|
|
7411
7434
|
advancedSettings:
|
|
7435
|
+
setEnv: Set by Environment Variable
|
|
7436
|
+
hideShow: Hide/show setting
|
|
7412
7437
|
label: Settings
|
|
7413
7438
|
subtext: Typical users will not need to change these. Proceed with caution, incorrect values can break your {appName} installation. Settings which have been customized from default settings are tagged 'Modified'.
|
|
7414
7439
|
show: Show
|
|
@@ -7480,6 +7505,7 @@ advancedSettings:
|
|
|
7480
7505
|
|
|
7481
7506
|
featureFlags:
|
|
7482
7507
|
label: Feature Flags
|
|
7508
|
+
title: "Are you sure?"
|
|
7483
7509
|
warning: |-
|
|
7484
7510
|
Feature flags allow {vendor} to gate certain features behind flags.
|
|
7485
7511
|
Features that are off by default should be considered experimental functionality.
|
|
@@ -7487,7 +7513,7 @@ featureFlags:
|
|
|
7487
7513
|
This will result in a short outage of the API and UI, but not affect running clusters or workloads.
|
|
7488
7514
|
promptActivate: Please confirm that you want to activate the feature flag "{flag}"
|
|
7489
7515
|
promptDeactivate: Please confirm that you want to deactivate the feature flag "{flag}"
|
|
7490
|
-
restartRequired: "Note: Updating this feature flag
|
|
7516
|
+
restartRequired: "Note: Updating this feature flag will restart {vendor}"
|
|
7491
7517
|
restart:
|
|
7492
7518
|
title: Waiting for Restart
|
|
7493
7519
|
wait: This may take a few moments
|
|
@@ -7496,6 +7522,7 @@ performance:
|
|
|
7496
7522
|
label: UI Performance Settings
|
|
7497
7523
|
settingName: Performance
|
|
7498
7524
|
experimental: This setting is experimental and may be removed or updated in future versions.
|
|
7525
|
+
deprecatedForSSP: The <i class="mr-5">"{setting}"</i> setting is now deprecated and will be removed in a future release. Please use the <a href="#ssp-setting" class="ml-5 mr-5">Server-side Pagination</a> setting instead.
|
|
7499
7526
|
incrementalLoad:
|
|
7500
7527
|
label: Incremental Loading
|
|
7501
7528
|
setting: You can configure the threshold above which incremental loading will be used.
|
|
@@ -7565,6 +7592,7 @@ performance:
|
|
|
7565
7592
|
resources:
|
|
7566
7593
|
generic: most resources in the cluster's 'More Resources' section
|
|
7567
7594
|
all: All Resources
|
|
7595
|
+
populateDefaults: Populate with latest pagination defaults
|
|
7568
7596
|
banner:
|
|
7569
7597
|
label: Fixed Banners
|
|
7570
7598
|
settingName: Banners
|
|
@@ -7759,7 +7787,7 @@ support:
|
|
|
7759
7787
|
text: Run SUSE Rancher products with confidence, knowing that the developers who built them are available to quickly resolve issues.
|
|
7760
7788
|
three:
|
|
7761
7789
|
title: Troubleshooting
|
|
7762
|
-
text: We focus on uncovering the root cause of any issue, whether it is related to
|
|
7790
|
+
text: We focus on uncovering the root cause of any issue, whether it is related to SUSE products, Kubernetes, Docker or your underlying infrastructure.
|
|
7763
7791
|
four:
|
|
7764
7792
|
title: Innovate with Freedom
|
|
7765
7793
|
text: Take advantage of our certified compatibility with a wide range of Kubernetes providers, operating systems, and open source software.
|
|
@@ -7310,7 +7310,7 @@ support:
|
|
|
7310
7310
|
text: 我们的开发人员会快速解决问题,因此你可以放心使用 SUSE Rancher 的产品。
|
|
7311
7311
|
three:
|
|
7312
7312
|
title: 故障排除
|
|
7313
|
-
text: 无论你使用的
|
|
7313
|
+
text: 无论你使用的 SUSE 产品、Kubernetes、Docker 还是底层基础架构出现问题,我们都会努力找到问题的根本原因。
|
|
7314
7314
|
four:
|
|
7315
7315
|
title: 自由创新
|
|
7316
7316
|
text: 基于我们与众多 Kubernetes 供应商、操作系统和开源软件认证的兼容性,实现自主创新。
|
|
@@ -264,7 +264,10 @@ export default {
|
|
|
264
264
|
:disabled="opt.disabled ? true : null"
|
|
265
265
|
:class="{divider: opt.divider}"
|
|
266
266
|
:data-testid="componentTestid + '-' + i + '-item'"
|
|
267
|
+
:tabindex="opt.divider ? -1 : 0"
|
|
267
268
|
@click="execute(opt, $event)"
|
|
269
|
+
@keyup.enter="execute(opt, $event)"
|
|
270
|
+
@keyup.space="execute(opt, $event)"
|
|
268
271
|
>
|
|
269
272
|
<IconOrSvg
|
|
270
273
|
v-if="opt.icon || opt.svg"
|
|
@@ -311,6 +314,11 @@ export default {
|
|
|
311
314
|
padding: 8px 10px;
|
|
312
315
|
margin: 0;
|
|
313
316
|
|
|
317
|
+
&:focus-visible {
|
|
318
|
+
@include focus-outline;
|
|
319
|
+
outline-offset: -2px;
|
|
320
|
+
}
|
|
321
|
+
|
|
314
322
|
&[disabled] {
|
|
315
323
|
cursor: not-allowed !important;
|
|
316
324
|
color: var(--disabled-text);
|
|
@@ -208,6 +208,10 @@ export default defineComponent({
|
|
|
208
208
|
return this.disabled || this.phase === ASYNC_BUTTON_STATES.WAITING;
|
|
209
209
|
},
|
|
210
210
|
|
|
211
|
+
isManualRefresh() {
|
|
212
|
+
return this.mode === 'manual-refresh';
|
|
213
|
+
},
|
|
214
|
+
|
|
211
215
|
tooltip(): { content: string, hideOnTargetClick: boolean} | null {
|
|
212
216
|
if ( this.labelAs === TOOLTIP ) {
|
|
213
217
|
return {
|
|
@@ -283,12 +287,14 @@ export default defineComponent({
|
|
|
283
287
|
:data-testid="componentTestid + '-async-button'"
|
|
284
288
|
@click="clicked"
|
|
285
289
|
>
|
|
286
|
-
<span
|
|
290
|
+
<span
|
|
291
|
+
v-if="isManualRefresh"
|
|
292
|
+
:class="{'mr-10': displayIcon && size !== 'sm', 'mr-5': displayIcon && size === 'sm'}"
|
|
293
|
+
>{{ t('action.refresh') }}</span>
|
|
287
294
|
<i
|
|
288
295
|
v-if="displayIcon"
|
|
289
296
|
v-clean-tooltip="tooltip"
|
|
290
|
-
:class="{icon: true, 'icon-lg': true, [displayIcon]: true}"
|
|
291
|
-
class="ml-5 mr-0"
|
|
297
|
+
:class="{icon: true, 'icon-lg': true, [displayIcon]: true, 'mr-0': isManualRefresh}"
|
|
292
298
|
/>
|
|
293
299
|
<span
|
|
294
300
|
v-if="labelAs === 'text' && displayLabel"
|
|
@@ -55,7 +55,12 @@ export default {
|
|
|
55
55
|
v-if="pref"
|
|
56
56
|
class="close-button"
|
|
57
57
|
data-testid="graphic-banner-close"
|
|
58
|
+
tabindex="0"
|
|
59
|
+
:aria-label="t('generic.close')"
|
|
60
|
+
role="button"
|
|
58
61
|
@click="hide()"
|
|
62
|
+
@keyup.enter="hide()"
|
|
63
|
+
@keyup.space="hide()"
|
|
59
64
|
>
|
|
60
65
|
<i class="icon icon-close" />
|
|
61
66
|
</div>
|
|
@@ -72,6 +77,11 @@ export default {
|
|
|
72
77
|
.close-button {
|
|
73
78
|
position: absolute;
|
|
74
79
|
visibility: hidden;
|
|
80
|
+
|
|
81
|
+
&:focus-visible {
|
|
82
|
+
@include focus-outline;
|
|
83
|
+
outline-offset: 2px;
|
|
84
|
+
}
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
&:hover .close-button {
|
|
@@ -33,6 +33,12 @@ const buttonClass = computed(() => {
|
|
|
33
33
|
.borderless {
|
|
34
34
|
background-color: transparent;
|
|
35
35
|
border: none;
|
|
36
|
+
|
|
37
|
+
&:focus-visible {
|
|
38
|
+
@include focus-outline;
|
|
39
|
+
outline-offset: -2px;
|
|
40
|
+
}
|
|
41
|
+
|
|
36
42
|
&:hover, &:focus {
|
|
37
43
|
background-color: var(--accent-btn);
|
|
38
44
|
box-shadow: none;
|
|
@@ -5,7 +5,7 @@ import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
|
5
5
|
export default {
|
|
6
6
|
name: 'CodeMirror',
|
|
7
7
|
|
|
8
|
-
emits: ['onReady', 'onInput', 'onChanges', 'onFocus'],
|
|
8
|
+
emits: ['onReady', 'onInput', 'onChanges', 'onFocus', 'validationChanged'],
|
|
9
9
|
|
|
10
10
|
props: {
|
|
11
11
|
/**
|
|
@@ -39,6 +39,7 @@ export default {
|
|
|
39
39
|
codeMirrorRef: null,
|
|
40
40
|
loaded: false,
|
|
41
41
|
removeKeyMapBox: false,
|
|
42
|
+
hasLintErrors: false,
|
|
42
43
|
};
|
|
43
44
|
},
|
|
44
45
|
|
|
@@ -65,6 +66,7 @@ export default {
|
|
|
65
66
|
foldGutter: true,
|
|
66
67
|
styleSelectedText: true,
|
|
67
68
|
showCursorWhenSelecting: true,
|
|
69
|
+
autocorrect: false,
|
|
68
70
|
};
|
|
69
71
|
|
|
70
72
|
if (this.asTextArea) {
|
|
@@ -76,6 +78,11 @@ export default {
|
|
|
76
78
|
|
|
77
79
|
Object.assign(out, this.options);
|
|
78
80
|
|
|
81
|
+
// parent components control lint with a boolean; if linting is enabled, we need to override that boolean with a custom error handler to wire lint errors into dashboard validation
|
|
82
|
+
if (this.options?.lint) {
|
|
83
|
+
out.lint = { onUpdateLinting: this.handleLintErrors };
|
|
84
|
+
}
|
|
85
|
+
|
|
79
86
|
return out;
|
|
80
87
|
},
|
|
81
88
|
|
|
@@ -104,7 +111,25 @@ export default {
|
|
|
104
111
|
}
|
|
105
112
|
},
|
|
106
113
|
|
|
114
|
+
watch: {
|
|
115
|
+
hasLintErrors(neu) {
|
|
116
|
+
this.$emit('validationChanged', !neu);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
107
120
|
methods: {
|
|
121
|
+
/**
|
|
122
|
+
* Codemirror yaml linting uses js-yaml parse
|
|
123
|
+
* it does not distinguish between warnings and errors so we will treat all yaml lint messages as errors
|
|
124
|
+
* other codemirror linters (eg json) will report from, to, severity where severity may be 'warning' or 'error'
|
|
125
|
+
* only 'error' level linting will trigger a validation event from this component
|
|
126
|
+
*/
|
|
127
|
+
handleLintErrors(diagnostics = []) {
|
|
128
|
+
const hasLintErrors = diagnostics.filter((d) => !d.severity || d.severity === 'error').length > 0;
|
|
129
|
+
|
|
130
|
+
this.hasLintErrors = hasLintErrors;
|
|
131
|
+
},
|
|
132
|
+
|
|
108
133
|
focus() {
|
|
109
134
|
if ( this.$refs.codeMirrorRef ) {
|
|
110
135
|
this.$refs.codeMirrorRef.cminstance.focus();
|
|
@@ -118,6 +143,8 @@ export default {
|
|
|
118
143
|
},
|
|
119
144
|
|
|
120
145
|
onReady(codeMirrorRef) {
|
|
146
|
+
this.$emit('validationChanged', true);
|
|
147
|
+
|
|
121
148
|
this.$nextTick(() => {
|
|
122
149
|
codeMirrorRef.refresh();
|
|
123
150
|
this.codeMirrorRef = codeMirrorRef;
|
|
@@ -110,6 +110,8 @@ export default {
|
|
|
110
110
|
<router-link
|
|
111
111
|
v-if="link.value.startsWith('/') "
|
|
112
112
|
:to="link.value"
|
|
113
|
+
role="link"
|
|
114
|
+
:aria-label="link.label"
|
|
113
115
|
>
|
|
114
116
|
{{ link.label }}
|
|
115
117
|
</router-link>
|
|
@@ -118,6 +120,8 @@ export default {
|
|
|
118
120
|
:href="link.value"
|
|
119
121
|
rel="noopener noreferrer nofollow"
|
|
120
122
|
target="_blank"
|
|
123
|
+
role="link"
|
|
124
|
+
:aria-label="link.label"
|
|
121
125
|
> {{ link.label }} </a>
|
|
122
126
|
</div>
|
|
123
127
|
<slot />
|
|
@@ -127,7 +131,11 @@ export default {
|
|
|
127
131
|
>
|
|
128
132
|
<a
|
|
129
133
|
class="link"
|
|
134
|
+
tabindex="0"
|
|
135
|
+
:aria-label="t('footer.wechat.title')"
|
|
136
|
+
role="link"
|
|
130
137
|
@click="show"
|
|
138
|
+
@keyup.enter="show"
|
|
131
139
|
>
|
|
132
140
|
{{ t('footer.wechat.title') }}
|
|
133
141
|
</a>
|
|
@@ -147,7 +155,12 @@ export default {
|
|
|
147
155
|
<div>
|
|
148
156
|
<button
|
|
149
157
|
class="btn role-primary"
|
|
158
|
+
tabindex="0"
|
|
159
|
+
:aria-label="t('generic.close')"
|
|
160
|
+
role="button"
|
|
150
161
|
@click="close"
|
|
162
|
+
@keyup.enter="close"
|
|
163
|
+
@keyup.space="close"
|
|
151
164
|
>
|
|
152
165
|
{{ t('generic.close') }}
|
|
153
166
|
</button>
|
|
@@ -120,6 +120,11 @@ export default {
|
|
|
120
120
|
default: () => []
|
|
121
121
|
},
|
|
122
122
|
|
|
123
|
+
stepsOptions: {
|
|
124
|
+
type: Object,
|
|
125
|
+
default: () => ({ editFirstStep: true })
|
|
126
|
+
},
|
|
127
|
+
|
|
123
128
|
// The set of labels to display for the finish AsyncButton
|
|
124
129
|
finishMode: {
|
|
125
130
|
type: String,
|
|
@@ -562,6 +567,7 @@ export default {
|
|
|
562
567
|
ref="Wizard"
|
|
563
568
|
:header-mode="mode"
|
|
564
569
|
:steps="steps"
|
|
570
|
+
:edit-first-step="stepsOptions.editFirstStep"
|
|
565
571
|
:errors="errors"
|
|
566
572
|
:finish-mode="finishMode"
|
|
567
573
|
class="wizard"
|
|
@@ -106,7 +106,10 @@ export default {
|
|
|
106
106
|
<div class="growl-text-title">
|
|
107
107
|
{{ growl.title }}
|
|
108
108
|
</div>
|
|
109
|
-
<p
|
|
109
|
+
<p
|
|
110
|
+
v-if="growl.message"
|
|
111
|
+
:class="{ 'has-title': !!growl.title }"
|
|
112
|
+
>
|
|
110
113
|
{{ growl.message }}
|
|
111
114
|
</p>
|
|
112
115
|
</div>
|
|
@@ -153,12 +156,16 @@ export default {
|
|
|
153
156
|
word-break: break-all;
|
|
154
157
|
box-shadow: 0 3px 5px 0px var(--shadow);
|
|
155
158
|
|
|
159
|
+
$growl-icon-size: 20px;
|
|
160
|
+
|
|
156
161
|
.icon-container {
|
|
157
162
|
align-self: center;
|
|
158
163
|
flex-basis: 10%;
|
|
159
164
|
padding: 10px 20px 10px 10px;
|
|
160
165
|
i {
|
|
161
|
-
font-size:
|
|
166
|
+
font-size: $growl-icon-size;
|
|
167
|
+
width: $growl-icon-size;
|
|
168
|
+
height: $growl-icon-size;
|
|
162
169
|
}
|
|
163
170
|
}
|
|
164
171
|
|
|
@@ -183,11 +190,14 @@ export default {
|
|
|
183
190
|
}
|
|
184
191
|
.growl-text-title {
|
|
185
192
|
font-size: 16px;
|
|
186
|
-
margin-bottom: 20px;
|
|
187
193
|
}
|
|
188
194
|
|
|
189
195
|
> P {
|
|
190
|
-
|
|
196
|
+
padding-top: 2px;
|
|
197
|
+
|
|
198
|
+
&.has-title {
|
|
199
|
+
margin-top: 5px;
|
|
200
|
+
}
|
|
191
201
|
}
|
|
192
202
|
}
|
|
193
203
|
}
|
|
@@ -11,7 +11,11 @@ export default {
|
|
|
11
11
|
mode: {
|
|
12
12
|
type: String,
|
|
13
13
|
default: ''
|
|
14
|
-
}
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
data() {
|
|
18
|
+
return { isLocaleSelectorOpen: false };
|
|
15
19
|
},
|
|
16
20
|
|
|
17
21
|
computed: {
|
|
@@ -40,8 +44,15 @@ export default {
|
|
|
40
44
|
},
|
|
41
45
|
|
|
42
46
|
methods: {
|
|
47
|
+
openLocaleSelector() {
|
|
48
|
+
this.isLocaleSelectorOpen = true;
|
|
49
|
+
},
|
|
50
|
+
closeLocaleSelector() {
|
|
51
|
+
this.isLocaleSelectorOpen = false;
|
|
52
|
+
},
|
|
43
53
|
switchLocale($event) {
|
|
44
54
|
this.$store.dispatch('i18n/switchTo', $event);
|
|
55
|
+
this.closeLocaleSelector();
|
|
45
56
|
},
|
|
46
57
|
}
|
|
47
58
|
};
|
|
@@ -50,13 +61,28 @@ export default {
|
|
|
50
61
|
<template>
|
|
51
62
|
<div>
|
|
52
63
|
<div v-if="mode === 'login'">
|
|
53
|
-
<div
|
|
64
|
+
<div
|
|
65
|
+
v-if="showLocale"
|
|
66
|
+
role="menu"
|
|
67
|
+
:aria-label="t('locale.menu')"
|
|
68
|
+
class="locale-login-container"
|
|
69
|
+
tabindex="0"
|
|
70
|
+
@click="openLocaleSelector"
|
|
71
|
+
@blur.capture="closeLocaleSelector"
|
|
72
|
+
@keyup.enter="openLocaleSelector"
|
|
73
|
+
@keyup.space="openLocaleSelector"
|
|
74
|
+
>
|
|
54
75
|
<v-dropdown
|
|
55
76
|
popperClass="localeSelector"
|
|
77
|
+
:shown="isLocaleSelectorOpen"
|
|
56
78
|
placement="top"
|
|
57
79
|
distance="8"
|
|
58
80
|
skidding="12"
|
|
59
|
-
:triggers="[
|
|
81
|
+
:triggers="[]"
|
|
82
|
+
:autoHide="false"
|
|
83
|
+
:flip="false"
|
|
84
|
+
:container="false"
|
|
85
|
+
@focus.capture="openLocaleSelector"
|
|
60
86
|
>
|
|
61
87
|
<a
|
|
62
88
|
data-testid="locale-selector"
|
|
@@ -74,13 +100,21 @@ export default {
|
|
|
74
100
|
v-if="showNone"
|
|
75
101
|
v-t="'locale.none'"
|
|
76
102
|
class="hand"
|
|
77
|
-
|
|
103
|
+
tabindex="0"
|
|
104
|
+
role="menuitem"
|
|
105
|
+
@click.stop="switchLocale('none')"
|
|
106
|
+
@keyup.enter.stop="switchLocale('none')"
|
|
107
|
+
@keyup.space.stop="switchLocale('none')"
|
|
78
108
|
/>
|
|
79
109
|
<li
|
|
80
110
|
v-for="(label, name) in availableLocales"
|
|
81
111
|
:key="name"
|
|
112
|
+
tabindex="0"
|
|
113
|
+
role="menuitem"
|
|
82
114
|
class="hand"
|
|
83
|
-
@click="switchLocale(name)"
|
|
115
|
+
@click.stop="switchLocale(name)"
|
|
116
|
+
@keyup.enter.stop="switchLocale(name)"
|
|
117
|
+
@keyup.space.stop="switchLocale(name)"
|
|
84
118
|
>
|
|
85
119
|
{{ label }}
|
|
86
120
|
</li>
|
|
@@ -114,6 +148,11 @@ export default {
|
|
|
114
148
|
border-radius: 4px;
|
|
115
149
|
}
|
|
116
150
|
|
|
151
|
+
.hand:focus-visible {
|
|
152
|
+
@include focus-outline;
|
|
153
|
+
outline-offset: 4px;
|
|
154
|
+
}
|
|
155
|
+
|
|
117
156
|
.locale-chooser {
|
|
118
157
|
cursor: pointer;
|
|
119
158
|
|
|
@@ -121,4 +160,9 @@ export default {
|
|
|
121
160
|
text-decoration: none;
|
|
122
161
|
}
|
|
123
162
|
}
|
|
163
|
+
|
|
164
|
+
.locale-login-container:focus-visible {
|
|
165
|
+
@include focus-outline;
|
|
166
|
+
outline-offset: 2px;
|
|
167
|
+
}
|
|
124
168
|
</style>
|
|
@@ -93,8 +93,8 @@ export default defineComponent({
|
|
|
93
93
|
},
|
|
94
94
|
|
|
95
95
|
computed: {
|
|
96
|
-
safeHeaders() {
|
|
97
|
-
const customHeaders = this.canPaginate ? this.paginationHeaders : this.headers;
|
|
96
|
+
safeHeaders(): any[] {
|
|
97
|
+
const customHeaders: any[] = this.canPaginate ? this.paginationHeaders : this.headers;
|
|
98
98
|
|
|
99
99
|
return customHeaders || this.$store.getters['type-map/headersFor'](this.schema, this.canPaginate);
|
|
100
100
|
}
|
|
@@ -109,7 +109,7 @@ export default defineComponent({
|
|
|
109
109
|
v-bind="$attrs"
|
|
110
110
|
:schema="schema"
|
|
111
111
|
:rows="rows"
|
|
112
|
-
:alt-loading="canPaginate"
|
|
112
|
+
:alt-loading="canPaginate && !isFirstLoad"
|
|
113
113
|
:loading="loading"
|
|
114
114
|
:groupable="groupable"
|
|
115
115
|
|
|
@@ -124,6 +124,7 @@ export default defineComponent({
|
|
|
124
124
|
<template
|
|
125
125
|
v-for="(_, slot) of $slots"
|
|
126
126
|
v-slot:[slot]="scope"
|
|
127
|
+
:key="slot"
|
|
127
128
|
>
|
|
128
129
|
<slot
|
|
129
130
|
:name="slot"
|
|
@@ -443,6 +443,9 @@ export default {
|
|
|
443
443
|
<router-link
|
|
444
444
|
v-if="location"
|
|
445
445
|
:to="location"
|
|
446
|
+
role="link"
|
|
447
|
+
class="masthead-resource-list-link"
|
|
448
|
+
:aria-label="parent.displayName"
|
|
446
449
|
>
|
|
447
450
|
{{ parent.displayName }}:
|
|
448
451
|
</router-link>
|
|
@@ -584,10 +587,10 @@ export default {
|
|
|
584
587
|
}
|
|
585
588
|
|
|
586
589
|
HEADER {
|
|
587
|
-
margin: 0;
|
|
590
|
+
margin: 0 0 0 -5px;
|
|
588
591
|
|
|
589
592
|
.title {
|
|
590
|
-
overflow: hidden;
|
|
593
|
+
overflow-x: hidden;
|
|
591
594
|
}
|
|
592
595
|
}
|
|
593
596
|
|
|
@@ -598,7 +601,7 @@ export default {
|
|
|
598
601
|
|
|
599
602
|
h1 {
|
|
600
603
|
margin: 0;
|
|
601
|
-
overflow: hidden;
|
|
604
|
+
overflow-x: hidden;
|
|
602
605
|
display: flex;
|
|
603
606
|
flex-direction: row;
|
|
604
607
|
align-items: center;
|
|
@@ -606,9 +609,13 @@ export default {
|
|
|
606
609
|
.masthead-resource-title {
|
|
607
610
|
padding: 0 8px;
|
|
608
611
|
text-overflow: ellipsis;
|
|
609
|
-
overflow: hidden;
|
|
612
|
+
overflow-x: hidden;
|
|
610
613
|
white-space: nowrap;
|
|
611
614
|
}
|
|
615
|
+
|
|
616
|
+
.masthead-resource-list-link {
|
|
617
|
+
margin: 5px;
|
|
618
|
+
}
|
|
612
619
|
}
|
|
613
620
|
}
|
|
614
621
|
|