dashboard-shell-shell 1.0.1000000116 → 1.0.1000000117
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/images/action.svg +6 -0
- package/assets/images/pl/logo.png +0 -0
- package/assets/styles/base/_functions.scss +0 -0
- package/assets/styles/base/_mixins.scss +1 -1
- package/assets/styles/global/_button.scss +17 -10
- package/assets/styles/global/_form.scss +2 -2
- package/assets/styles/global/_labeled-input.scss +6 -2
- package/assets/styles/global/_select.scss +6 -7
- package/assets/styles/global/_table.scss +3 -2
- package/assets/styles/global/_tooltip.scss +8 -1
- package/assets/styles/themes/_dark.scss +2 -0
- package/assets/styles/themes/_light.scss +5 -2
- package/assets/styles/vendor/vue-select.scss +2 -1
- package/assets/translations/en-us.yaml +1 -3
- package/assets/translations/zh-hans.yaml +51 -28
- package/components/ActionDropdown.vue +1 -0
- package/components/ActionMenuShell.vue +6 -3
- package/components/BrandImage.vue +22 -0
- package/components/ClusterIconMenu.vue +1 -1
- package/components/CodeMirror.vue +1 -0
- package/components/CruResource.vue +1 -1
- package/components/CruResourceFooter.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +4 -24
- package/components/GlobalRoleBindings.vue +112 -48
- package/components/IndentedPanel.vue +4 -10
- package/components/PromptRemove.vue +3 -3
- package/components/ResourceDetail/Masthead.vue +190 -242
- package/components/ResourceDetail/index.vue +20 -5
- package/components/ResourceList/Masthead.vue +146 -84
- package/components/ResourceList/ResourceLoadingIndicator.vue +5 -2
- package/components/ResourceTable.vue +76 -1
- package/components/SideNav.vue +66 -29
- package/components/SortableTable/THead.vue +6 -0
- package/components/SortableTable/index.vue +481 -388
- package/components/Tabbed/index.vue +4 -5
- package/components/auth/Principal.vue +3 -2
- package/components/auth/RoleDetailEdit.vue +58 -5
- package/components/auth/SelectPrincipal.vue +1 -0
- package/components/form/BannerSettings.vue +18 -16
- package/components/form/ChangePassword.vue +4 -4
- package/components/form/ColorInput.vue +32 -8
- package/components/form/Footer.vue +1 -1
- package/components/form/InputWithSelect.vue +2 -0
- package/components/form/KeyValue.vue +31 -7
- package/components/form/LabeledSelect.vue +178 -178
- package/components/form/Members/ClusterPermissionsEditor.vue +1 -2
- package/components/form/Members/MembershipEditor.vue +1 -1
- package/components/form/NameNsDescription.vue +24 -11
- package/components/form/Password.vue +6 -2
- package/components/form/ResourceQuota/Namespace.vue +1 -1
- package/components/form/ResourceQuota/NamespaceRow.vue +13 -10
- package/components/form/ResourceQuota/ProjectRow.vue +0 -1
- package/components/form/Select.vue +2 -2
- package/components/nav/Favorite.vue +5 -1
- package/components/nav/Group.vue +69 -23
- package/components/nav/Header.vue +82 -17
- package/components/nav/HeaderPageActionMenu.vue +1 -0
- package/components/nav/NamespaceFilter.vue +0 -3
- package/components/nav/TopLevelMenu.vue +182 -119
- package/components/nav/Type.vue +48 -11
- package/composables/useClickOutside.ts +1 -1
- package/config/product/auth.js +16 -7
- package/config/product/explorer.js +1 -1
- package/config/product/settings.js +17 -8
- package/config/settings.ts +28 -0
- package/edit/management.cattle.io.user.vue +17 -4
- package/edit/networking.k8s.io.ingress/RulePath.vue +1 -1
- package/edit/token.vue +1 -1
- package/list/harvesterhci.io.management.cluster.vue +17 -0
- package/list/management.cattle.io.setting.vue +22 -13
- package/list/management.cattle.io.user.vue +25 -14
- package/list/provisioning.cattle.io.cluster.vue +6 -7
- package/mixins/brand.js +17 -0
- package/package.json +1 -1
- package/pages/auth/login.vue +84 -29
- package/pages/c/_cluster/auth/roles/index.vue +61 -14
- package/pages/c/_cluster/settings/banners.vue +174 -101
- package/pages/c/_cluster/settings/brand.vue +348 -301
- package/pages/c/_cluster/settings/performance.vue +61 -38
- package/pages/home.vue +70 -21
- package/pages/prefs.vue +25 -23
- package/pkg/tsconfig.json +9 -9
- package/pkg/vue.config.js +1 -1
- package/promptRemove/mixin/roleDeletionCheck.js +2 -2
- package/scripts/clean +0 -0
- package/scripts/extension/bundle +0 -0
- package/scripts/extension/helm/scripts/package +0 -0
- package/scripts/extension/helm/scripts/patch +0 -0
- package/scripts/extension/helm/scripts/version +0 -0
- package/scripts/extension/helmpatch +0 -0
- package/scripts/extension/parse-tag-name +0 -0
- package/scripts/extension/publish +0 -0
- package/scripts/publish-shell.sh +86 -60
- package/scripts/serve-pkgs +0 -0
- package/scripts/sync-shell-deps +0 -0
- package/scripts/typegen.sh +44 -28
- package/store/i18n.js +5 -5
- package/store/prefs.js +17 -5
- package/store/type-map.js +2 -1
- package/types/shell/index.d.ts +1 -1
- package/utils/error.js +4 -0
- package/utils/router.js +3 -3
- package/vue.config.js +1 -6
- package/components/rancherResourceDetail/Masthead.vue +0 -769
- package/components/rancherResourceDetail/__tests__/Masthead.test.ts +0 -65
- package/components/rancherResourceDetail/index.vue +0 -591
- package/components/rancherResourceList/Masthead.vue +0 -375
- package/components/rancherResourceList/ResourceLoadingIndicator.vue +0 -140
- package/components/rancherResourceList/index.vue +0 -307
- package/components/rancherResourceList/resource-list.config.js +0 -7
- package/components/rancherResourceTable.vue +0 -783
- package/components/rancherSortableTable/THead.vue +0 -561
- package/components/rancherSortableTable/actions.js +0 -153
- package/components/rancherSortableTable/advanced-filtering.js +0 -272
- package/components/rancherSortableTable/debug.js +0 -117
- package/components/rancherSortableTable/filtering.js +0 -290
- package/components/rancherSortableTable/grouping.js +0 -48
- package/components/rancherSortableTable/index.vue +0 -2712
- package/components/rancherSortableTable/paging.js +0 -155
- package/components/rancherSortableTable/selection.js +0 -629
- package/components/rancherSortableTable/sortable-config.ts +0 -4
- package/components/rancherSortableTable/sorting.js +0 -129
- package/types/cloud-shell/index.d.ts +0 -11014
- /package/components/{rancherResourceList → ResourceList}/Masthead-btn.vue +0 -0
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
import { ADV_FILTER_ALL_COLS_VALUE, ADV_FILTER_ALL_COLS_LABEL } from './filtering';
|
|
2
|
-
|
|
3
|
-
const DEFAULT_ADV_FILTER_COLS_VALUE = ADV_FILTER_ALL_COLS_VALUE;
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
props: {
|
|
7
|
-
/**
|
|
8
|
-
* Group value
|
|
9
|
-
* To be used on the THead component when adv filtering is present
|
|
10
|
-
*/
|
|
11
|
-
group: {
|
|
12
|
-
type: String,
|
|
13
|
-
default: () => ''
|
|
14
|
-
},
|
|
15
|
-
/**
|
|
16
|
-
* Group options
|
|
17
|
-
* All of the grouping options available to be used on the THead component when adv filtering is present
|
|
18
|
-
*/
|
|
19
|
-
groupOptions: {
|
|
20
|
-
type: Array,
|
|
21
|
-
default: () => []
|
|
22
|
-
},
|
|
23
|
-
/**
|
|
24
|
-
* Flag that controls visibility of advanced filtering feature
|
|
25
|
-
*/
|
|
26
|
-
hasAdvancedFiltering: {
|
|
27
|
-
type: Boolean,
|
|
28
|
-
default: false
|
|
29
|
-
},
|
|
30
|
-
/**
|
|
31
|
-
* Flag that controls visibility of labels as possibe toggable cols to be displayed on the Sortable Table
|
|
32
|
-
*/
|
|
33
|
-
advFilterHideLabelsAsCols: {
|
|
34
|
-
type: Boolean,
|
|
35
|
-
default: false
|
|
36
|
-
},
|
|
37
|
-
/**
|
|
38
|
-
* Flag that prevents filtering by labels
|
|
39
|
-
*/
|
|
40
|
-
advFilterPreventFilteringLabels: {
|
|
41
|
-
type: Boolean,
|
|
42
|
-
default: false
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
data() {
|
|
46
|
-
return {
|
|
47
|
-
columnOptions: [],
|
|
48
|
-
colOptionsWatcher: null,
|
|
49
|
-
advancedFilteringVisibility: false,
|
|
50
|
-
advancedFilteringValues: [],
|
|
51
|
-
advFilterSearchTerm: null,
|
|
52
|
-
advFilterSelectedProp: DEFAULT_ADV_FILTER_COLS_VALUE,
|
|
53
|
-
advFilterSelectedLabel: ADV_FILTER_ALL_COLS_LABEL,
|
|
54
|
-
column: null,
|
|
55
|
-
};
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
mounted() {
|
|
59
|
-
if (this.hasAdvancedFiltering) {
|
|
60
|
-
// trigger to first populate the cols options for filters
|
|
61
|
-
this.updateColsOptions();
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
watch: {
|
|
66
|
-
advancedFilteringValues() {
|
|
67
|
-
// passing different dummy args to make sure update is triggered
|
|
68
|
-
this.watcherUpdateLiveAndDelayed(true, false);
|
|
69
|
-
},
|
|
70
|
-
advancedFilteringVisibility(neu) {
|
|
71
|
-
if (neu) {
|
|
72
|
-
// check if user clicked outside the advanced filter box
|
|
73
|
-
window.addEventListener('click', this.onClickOutside);
|
|
74
|
-
|
|
75
|
-
// update filtering options and toggable cols every time dropdown is open
|
|
76
|
-
this.updateColsOptions();
|
|
77
|
-
} else {
|
|
78
|
-
// unregister click event
|
|
79
|
-
window.removeEventListener('click', this.onClickOutside);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
computed: {
|
|
85
|
-
advFilterSelectOptions() {
|
|
86
|
-
return this.columnOptions.filter((c) => c.isFilter && !c.preventFiltering);
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
advGroupOptions() {
|
|
90
|
-
return this.groupOptions.map((item) => {
|
|
91
|
-
return {
|
|
92
|
-
label: this.t(item.tooltipKey),
|
|
93
|
-
value: item.value
|
|
94
|
-
};
|
|
95
|
-
});
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
methods: {
|
|
100
|
-
handleColsVisibilyAndFiltering(cols) {
|
|
101
|
-
const allCols = cols;
|
|
102
|
-
|
|
103
|
-
this.columnOptions.forEach((advCol) => {
|
|
104
|
-
if (advCol.isTableOption) {
|
|
105
|
-
const index = allCols.findIndex((col) => col.name === advCol.name);
|
|
106
|
-
|
|
107
|
-
if (index !== -1) {
|
|
108
|
-
allCols[index].isColVisible = advCol.isColVisible;
|
|
109
|
-
allCols[index].isFilter = advCol.isFilter;
|
|
110
|
-
} else {
|
|
111
|
-
allCols.push(advCol);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
return allCols;
|
|
117
|
-
},
|
|
118
|
-
// advanced filtering methods
|
|
119
|
-
setColsOptions() {
|
|
120
|
-
let opts = [];
|
|
121
|
-
const rowLabels = [];
|
|
122
|
-
const headerProps = [];
|
|
123
|
-
|
|
124
|
-
// Filter out any columns that are too heavy to show for large page sizes
|
|
125
|
-
const filteredHeaders = this.headers.slice().filter((c) => (!c.maxPageSize || (c.maxPageSize && c.maxPageSize >= this.perPage)));
|
|
126
|
-
|
|
127
|
-
// add table cols from config (headers)
|
|
128
|
-
filteredHeaders.forEach((prop) => {
|
|
129
|
-
const name = prop.name;
|
|
130
|
-
const label = prop.labelKey ? this.t(`${ prop.labelKey }`) : prop.label;
|
|
131
|
-
const isFilter = !!((!Object.keys(prop).includes('search') || prop.search));
|
|
132
|
-
let sortVal = prop.sort;
|
|
133
|
-
const valueProp = prop.valueProp || prop.value;
|
|
134
|
-
let value = null;
|
|
135
|
-
let isColVisible = true;
|
|
136
|
-
|
|
137
|
-
if (prop.sort && valueProp) {
|
|
138
|
-
if (typeof prop.sort === 'string') {
|
|
139
|
-
sortVal = prop.sort.includes(':') ? [prop.sort.split(':')[0]] : [prop.sort];
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!sortVal.includes(valueProp)) {
|
|
143
|
-
value = JSON.stringify(sortVal.concat([valueProp]));
|
|
144
|
-
} else {
|
|
145
|
-
value = JSON.stringify([valueProp]);
|
|
146
|
-
}
|
|
147
|
-
} else if (valueProp) {
|
|
148
|
-
value = JSON.stringify([valueProp]);
|
|
149
|
-
} else {
|
|
150
|
-
value = null;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// maintain current visibility of cols if they exist already
|
|
154
|
-
if (this.columnOptions?.length) {
|
|
155
|
-
const opt = this.columnOptions.find((colOpt) => colOpt.name === name && colOpt.label === label);
|
|
156
|
-
|
|
157
|
-
if (opt) {
|
|
158
|
-
isColVisible = opt.isColVisible;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
headerProps.push({
|
|
163
|
-
name,
|
|
164
|
-
label,
|
|
165
|
-
value,
|
|
166
|
-
isFilter,
|
|
167
|
-
isTableOption: true,
|
|
168
|
-
isColVisible
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// add labels as table cols
|
|
173
|
-
if (this.rows.length) {
|
|
174
|
-
this.rows.forEach((row) => {
|
|
175
|
-
if (row.metadata?.labels && Object.keys(row.metadata?.labels).length) {
|
|
176
|
-
Object.keys(row.metadata?.labels).forEach((label) => {
|
|
177
|
-
const res = {
|
|
178
|
-
name: label,
|
|
179
|
-
label,
|
|
180
|
-
value: `metadata.labels.${ label }`,
|
|
181
|
-
isFilter: true,
|
|
182
|
-
isTableOption: true,
|
|
183
|
-
isColVisible: false,
|
|
184
|
-
isLabel: true,
|
|
185
|
-
preventFiltering: this.advFilterPreventFilteringLabels,
|
|
186
|
-
preventColToggle: this.advFilterHideLabelsAsCols
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
// maintain current visibility of cols if they exist already
|
|
190
|
-
if (this.columnOptions?.length) {
|
|
191
|
-
const opt = this.columnOptions.find((colOpt) => colOpt.name === label && colOpt.label === label);
|
|
192
|
-
|
|
193
|
-
if (opt) {
|
|
194
|
-
res.isColVisible = opt.isColVisible;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (!rowLabels.filter((row) => row.label === label).length) {
|
|
199
|
-
rowLabels.push(res);
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
opts = headerProps.concat(rowLabels);
|
|
207
|
-
|
|
208
|
-
// add find on all cols option...
|
|
209
|
-
if (opts.length) {
|
|
210
|
-
opts.unshift({
|
|
211
|
-
name: ADV_FILTER_ALL_COLS_LABEL,
|
|
212
|
-
label: ADV_FILTER_ALL_COLS_LABEL,
|
|
213
|
-
value: ADV_FILTER_ALL_COLS_VALUE,
|
|
214
|
-
isFilter: true,
|
|
215
|
-
isTableOption: false
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return opts;
|
|
220
|
-
},
|
|
221
|
-
addAdvancedFilter() {
|
|
222
|
-
// set new advanced filter
|
|
223
|
-
if (this.advFilterSelectedProp && this.advFilterSearchTerm) {
|
|
224
|
-
this.advancedFilteringValues.push({
|
|
225
|
-
prop: this.advFilterSelectedProp,
|
|
226
|
-
value: this.advFilterSearchTerm,
|
|
227
|
-
label: this.advFilterSelectedLabel
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
this.eventualSearchQuery = this.advancedFilteringValues;
|
|
231
|
-
|
|
232
|
-
this.advancedFilteringVisibility = false;
|
|
233
|
-
this.advFilterSelectedProp = DEFAULT_ADV_FILTER_COLS_VALUE;
|
|
234
|
-
this.advFilterSelectedLabel = ADV_FILTER_ALL_COLS_LABEL;
|
|
235
|
-
this.advFilterSearchTerm = null;
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
clearAllAdvancedFilters() {
|
|
239
|
-
this.advancedFilteringValues = [];
|
|
240
|
-
this.eventualSearchQuery = this.advancedFilteringValues;
|
|
241
|
-
|
|
242
|
-
this.advancedFilteringVisibility = false;
|
|
243
|
-
this.advFilterSelectedProp = DEFAULT_ADV_FILTER_COLS_VALUE;
|
|
244
|
-
this.advFilterSelectedLabel = ADV_FILTER_ALL_COLS_LABEL;
|
|
245
|
-
this.advFilterSearchTerm = null;
|
|
246
|
-
},
|
|
247
|
-
clearAdvancedFilter(index) {
|
|
248
|
-
this.advancedFilteringValues.splice(index, 1);
|
|
249
|
-
this.eventualSearchQuery = this.advancedFilteringValues;
|
|
250
|
-
},
|
|
251
|
-
onClickOutside(event) {
|
|
252
|
-
const advFilterBox = this.$refs['advanced-filter-group'];
|
|
253
|
-
|
|
254
|
-
if (!advFilterBox || advFilterBox.contains(event.target)) {
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
this.advancedFilteringVisibility = false;
|
|
258
|
-
},
|
|
259
|
-
updateColsOptions() {
|
|
260
|
-
this.columnOptions = this.setColsOptions();
|
|
261
|
-
},
|
|
262
|
-
|
|
263
|
-
// cols visibility
|
|
264
|
-
changeColVisibility(colData) {
|
|
265
|
-
const index = this.columnOptions.findIndex((col) => col.label === colData.label);
|
|
266
|
-
|
|
267
|
-
if (index !== -1) {
|
|
268
|
-
this.columnOptions[index].isColVisible = colData.value;
|
|
269
|
-
}
|
|
270
|
-
},
|
|
271
|
-
},
|
|
272
|
-
};
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
|
|
3
|
-
// =========================================================================================
|
|
4
|
-
// Debug helper
|
|
5
|
-
// Adds a bunch of watches to help dignose computed properties bring re-evaluated
|
|
6
|
-
// =========================================================================================
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
watch: {
|
|
10
|
-
sortFields(neu, old) {
|
|
11
|
-
console.log('sortFields changed ------------------------------------------------');
|
|
12
|
-
console.log(neu);
|
|
13
|
-
console.log(old);
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
descending(neu, old) {
|
|
17
|
-
console.log('descending changed ------------------------------------------------');
|
|
18
|
-
console.log(neu);
|
|
19
|
-
console.log(old);
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
rows(neu, old) {
|
|
23
|
-
console.log('rows changed ------------------------------------------------');
|
|
24
|
-
console.log(neu.length);
|
|
25
|
-
console.log(old.length);
|
|
26
|
-
|
|
27
|
-
// console.log('Checking rows');
|
|
28
|
-
|
|
29
|
-
// let diff = 0;
|
|
30
|
-
|
|
31
|
-
// for (let i=0;i<neu.length;i++) {
|
|
32
|
-
// const a = JSON.stringify(neu[i]);
|
|
33
|
-
// const b = JSON.stringify(old[i]);
|
|
34
|
-
|
|
35
|
-
// if (a !== b) {
|
|
36
|
-
// console.log('rows differ ' + i);
|
|
37
|
-
// diff++;
|
|
38
|
-
// }
|
|
39
|
-
// }
|
|
40
|
-
|
|
41
|
-
// console.log(diff + ' rows changed');
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
pagingDisplay(neu, old) {
|
|
45
|
-
console.log('pagingDisplay changed ------------------------------------------------');
|
|
46
|
-
console.log(neu.length);
|
|
47
|
-
console.log(old.length);
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
totalPages(neu, old) {
|
|
51
|
-
console.log('totalPages changed ------------------------------------------------');
|
|
52
|
-
console.log(neu.length);
|
|
53
|
-
console.log(old.length);
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
pagedRows(neu, old) {
|
|
57
|
-
console.log('pagedRows changed ------------------------------------------------');
|
|
58
|
-
console.log(neu.length);
|
|
59
|
-
console.log(old.length);
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
arrangedRows(neu, old) {
|
|
63
|
-
console.log('arrangedRows changed ------------------------------------------------');
|
|
64
|
-
console.log(neu.length);
|
|
65
|
-
console.log(old.length);
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
searchFields(neu, old) {
|
|
69
|
-
console.log('searchFields changed ------------------------------------------------');
|
|
70
|
-
console.log(neu.length);
|
|
71
|
-
console.log(old.length);
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
filteredRows(neu, old) {
|
|
75
|
-
console.log('filteredRows changed ------------------------------------------------');
|
|
76
|
-
console.log(neu.length);
|
|
77
|
-
console.log(old.length);
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
groupedRows(neu, old) {
|
|
81
|
-
console.log('groupedRows changed ------------------------------------------------');
|
|
82
|
-
console.log(neu.length);
|
|
83
|
-
console.log(old.length);
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
headers(neu, old) {
|
|
87
|
-
console.log('headers changed ------------------------------------------------');
|
|
88
|
-
console.log(neu);
|
|
89
|
-
console.log(old);
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
displayRows(neu, old) {
|
|
93
|
-
console.log('displayRows changed ------------------------------------------------');
|
|
94
|
-
console.log(neu);
|
|
95
|
-
console.log(old);
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
groupBy(neu, old) {
|
|
99
|
-
console.log('groupBy changed ------------------------------------------------');
|
|
100
|
-
console.log(neu);
|
|
101
|
-
console.log(old);
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
groupSort(neu, old) {
|
|
105
|
-
console.log('groupSort changed ------------------------------------------------');
|
|
106
|
-
console.log(neu);
|
|
107
|
-
console.log(old);
|
|
108
|
-
},
|
|
109
|
-
|
|
110
|
-
columns(neu, old) {
|
|
111
|
-
console.log('columns changed ------------------------------------------------');
|
|
112
|
-
console.log(neu);
|
|
113
|
-
console.log(old);
|
|
114
|
-
},
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
/* eslint-enable no-console */
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import { get } from '@shell/utils/object';
|
|
2
|
-
import { addObject, addObjects, isArray, removeAt } from '@shell/utils/array';
|
|
3
|
-
|
|
4
|
-
export const ADV_FILTER_ALL_COLS_VALUE = 'allcols';
|
|
5
|
-
export const ADV_FILTER_ALL_COLS_LABEL = 'All Columns';
|
|
6
|
-
const LABEL_IDENTIFIER = ':::islabel';
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
data() {
|
|
10
|
-
return {
|
|
11
|
-
searchQuery: null,
|
|
12
|
-
previousFilter: null,
|
|
13
|
-
previousResult: null,
|
|
14
|
-
};
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
computed: {
|
|
18
|
-
searchFields() {
|
|
19
|
-
const out = columnsToSearchField(this.columns);
|
|
20
|
-
|
|
21
|
-
if ( this.extraSearchFields ) {
|
|
22
|
-
addObjects(out, this.extraSearchFields);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return out;
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
/*
|
|
29
|
-
subFields: computed('subHeaders.@each.{searchField,name}', 'extraSearchSubFields.[]', function() {
|
|
30
|
-
let out = headersToSearchField(get(this, 'subHeaders'));
|
|
31
|
-
|
|
32
|
-
return out.addObjects(get(this, 'extraSearchSubFields') || []);
|
|
33
|
-
}),
|
|
34
|
-
*/
|
|
35
|
-
filteredRows() {
|
|
36
|
-
if (this.externalPaginationEnabled) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// PROP hasAdvancedFiltering comes from Advanced Filtering mixin (careful changing data var there...)
|
|
41
|
-
if (!this.hasAdvancedFiltering) {
|
|
42
|
-
return this.handleFiltering();
|
|
43
|
-
} else {
|
|
44
|
-
return this.handleAdvancedFiltering();
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
methods: {
|
|
50
|
-
handleAdvancedFiltering() {
|
|
51
|
-
this.subMatches = null;
|
|
52
|
-
|
|
53
|
-
if (this.searchQuery.length) {
|
|
54
|
-
const out = (this.arrangedRows || []).slice();
|
|
55
|
-
|
|
56
|
-
const res = out.filter((row) => {
|
|
57
|
-
return this.searchQuery.every((f) => {
|
|
58
|
-
if (f.prop === ADV_FILTER_ALL_COLS_VALUE) {
|
|
59
|
-
// advFilterSelectOptions comes from Advanced Filtering mixin
|
|
60
|
-
// remove the All Columns option from the list so that we don't iterate over it
|
|
61
|
-
const allCols = this.advFilterSelectOptions.slice(1);
|
|
62
|
-
let searchFields = [];
|
|
63
|
-
|
|
64
|
-
allCols.forEach((col) => {
|
|
65
|
-
if (col.value.includes('[') && col.value.includes(']')) {
|
|
66
|
-
searchFields = searchFields.concat(JSON.parse(col.value));
|
|
67
|
-
} else {
|
|
68
|
-
// this means we are on the presence of a label, which should be dealt
|
|
69
|
-
// carefully because of object path such row.metadata.labels."app.kubernetes.io/managed-by
|
|
70
|
-
const value = col.isLabel ? `${ col.label }${ LABEL_IDENTIFIER }` : col.value;
|
|
71
|
-
|
|
72
|
-
searchFields.push(value);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
return handleStringSearch(searchFields, [f.value], row);
|
|
77
|
-
} else {
|
|
78
|
-
if (f.prop.includes('[') && f.prop.includes(']')) {
|
|
79
|
-
return handleStringSearch(JSON.parse(f.prop), [f.value], row);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
let prop = f.prop;
|
|
83
|
-
|
|
84
|
-
// this means we are on the presence of a label, which should be dealt
|
|
85
|
-
// carefully because of object path such row.metadata.labels."app.kubernetes.io/managed-by"
|
|
86
|
-
if (f.prop.includes('metadata.labels')) {
|
|
87
|
-
prop = `${ f.label }${ LABEL_IDENTIFIER }`;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return handleStringSearch([prop], [f.value], row);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
return res;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// return arrangedRows array if we don't have anything to search for...
|
|
99
|
-
return this.arrangedRows;
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
handleFiltering() {
|
|
103
|
-
const searchText = (this.searchQuery || '').trim().toLowerCase();
|
|
104
|
-
let out;
|
|
105
|
-
|
|
106
|
-
if ( searchText && this.previousResult && searchText.startsWith(this.previousFilter) ) {
|
|
107
|
-
// If the new search is an addition to the last one, we can start with the same set of results as last time
|
|
108
|
-
// and filter those down, since adding more searchText can only reduce the number of results.
|
|
109
|
-
out = this.previousResult.slice();
|
|
110
|
-
} else {
|
|
111
|
-
this.previousResult = null;
|
|
112
|
-
out = (this.arrangedRows || []).slice();
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
this.previousFilter = searchText;
|
|
116
|
-
|
|
117
|
-
if ( !searchText.length ) {
|
|
118
|
-
this.subMatches = null;
|
|
119
|
-
this.previousResult = null;
|
|
120
|
-
|
|
121
|
-
return out;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const searchFields = this.searchFields;
|
|
125
|
-
const searchTokens = searchText.split(/\s*[, ]\s*/);
|
|
126
|
-
const subSearch = this.subSearch;
|
|
127
|
-
const subFields = this.subFields;
|
|
128
|
-
const subMatches = {};
|
|
129
|
-
|
|
130
|
-
for ( let i = out.length - 1 ; i >= 0 ; i-- ) {
|
|
131
|
-
const row = out[i];
|
|
132
|
-
let hits = 0;
|
|
133
|
-
let mainFound = true;
|
|
134
|
-
|
|
135
|
-
mainFound = handleStringSearch(searchFields, searchTokens, row);
|
|
136
|
-
|
|
137
|
-
if ( subFields && subSearch) {
|
|
138
|
-
const subRows = row[subSearch] || [];
|
|
139
|
-
|
|
140
|
-
for ( let k = subRows.length - 1 ; k >= 0 ; k-- ) {
|
|
141
|
-
let subFound = true;
|
|
142
|
-
|
|
143
|
-
subFound = handleStringSearch(subFields, searchTokens, row);
|
|
144
|
-
|
|
145
|
-
if ( subFound ) {
|
|
146
|
-
hits++;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
subMatches[get(row, this.keyField)] = hits;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if ( !mainFound && hits === 0 ) {
|
|
154
|
-
removeAt(out, i);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
this.subMatches = subMatches;
|
|
159
|
-
this.previousResult = out;
|
|
160
|
-
|
|
161
|
-
return out;
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
|
|
165
|
-
watch: {
|
|
166
|
-
arrangedRows(q) {
|
|
167
|
-
// The rows changed so the old filter result is no longer useful
|
|
168
|
-
this.previousResult = null;
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
searchQuery() {
|
|
172
|
-
this.debouncedPaginationChanged();
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
function columnsToSearchField(columns) {
|
|
178
|
-
const out = [];
|
|
179
|
-
|
|
180
|
-
(columns || []).forEach((column) => {
|
|
181
|
-
const field = column.search;
|
|
182
|
-
|
|
183
|
-
if ( field ) {
|
|
184
|
-
if ( typeof field === 'string' ) {
|
|
185
|
-
addObject(out, field);
|
|
186
|
-
} else if ( isArray(field) ) {
|
|
187
|
-
addObjects(out, field);
|
|
188
|
-
}
|
|
189
|
-
} else if ( field === false ) {
|
|
190
|
-
// Don't add the name
|
|
191
|
-
} else {
|
|
192
|
-
// Use value/name as the default
|
|
193
|
-
addObject(out, column.value || column.name);
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
return out.filter((x) => !!x);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const ipLike = /^[0-9a-f\.:]+$/i;
|
|
201
|
-
|
|
202
|
-
function handleStringSearch(searchFields, searchTokens, row) {
|
|
203
|
-
for ( let j = 0 ; j < searchTokens.length ; j++ ) {
|
|
204
|
-
let expect = true;
|
|
205
|
-
let token = searchTokens[j];
|
|
206
|
-
|
|
207
|
-
if ( token.substr(0, 1) === '!' ) {
|
|
208
|
-
expect = false;
|
|
209
|
-
token = token.substr(1);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if ( token && matches(searchFields, token, row) !== expect ) {
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
return true;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function matches(fields, token, item) {
|
|
221
|
-
for ( let field of fields ) {
|
|
222
|
-
if ( !field ) {
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// some items might not even have metadata.labels or metadata.labels.something... ignore those items. Nothing to filter by
|
|
227
|
-
if (typeof field !== 'function' &&
|
|
228
|
-
field.includes(LABEL_IDENTIFIER) &&
|
|
229
|
-
(!item.metadata.labels || !item.metadata.labels[field.replace(LABEL_IDENTIFIER, '')])) {
|
|
230
|
-
continue;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
let modifier;
|
|
234
|
-
let val;
|
|
235
|
-
|
|
236
|
-
if (typeof field === 'function') {
|
|
237
|
-
val = field(item);
|
|
238
|
-
} else if (field.includes(LABEL_IDENTIFIER)) {
|
|
239
|
-
val = item.metadata.labels[field.replace(LABEL_IDENTIFIER, '')];
|
|
240
|
-
} else {
|
|
241
|
-
const idx = field.indexOf(':');
|
|
242
|
-
|
|
243
|
-
if ( idx > 0 ) {
|
|
244
|
-
modifier = field.substr(idx + 1);
|
|
245
|
-
field = field.substr(0, idx);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if ( field.includes('.') ) {
|
|
249
|
-
val = get(item, field);
|
|
250
|
-
} else {
|
|
251
|
-
val = item[field];
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if ( val === undefined ) {
|
|
256
|
-
continue;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
val = (`${ val }`).toLowerCase();
|
|
260
|
-
if ( !val ) {
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if ( !modifier ) {
|
|
265
|
-
if ( val.includes((`${ token }`).toLowerCase()) ) {
|
|
266
|
-
return true;
|
|
267
|
-
}
|
|
268
|
-
} else if ( modifier === 'exact' ) {
|
|
269
|
-
if ( val === token ) {
|
|
270
|
-
return true;
|
|
271
|
-
}
|
|
272
|
-
} else if ( modifier === 'ip' ) {
|
|
273
|
-
const tokenMayBeIp = ipLike.test(token);
|
|
274
|
-
|
|
275
|
-
if ( tokenMayBeIp ) {
|
|
276
|
-
const re = new RegExp(`(?:^|\\.)${ token }(?:\\.|$)`);
|
|
277
|
-
|
|
278
|
-
if ( re.test(val) ) {
|
|
279
|
-
return true;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
} else if ( modifier === 'prefix' ) {
|
|
283
|
-
if ( val.indexOf(token) === 0) {
|
|
284
|
-
return true;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return false;
|
|
290
|
-
}
|