Skip to content

Commit 021cfac

Browse files
authored
Merge pull request #13703 from rak-phillip/task/13702-form-components-data
Refactor form components so data prop no longer contains init logic
2 parents c86e7b2 + 431022e commit 021cfac

29 files changed

+780
-613
lines changed

jest.setup.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,18 @@ jest.mock('@shell/composables/useI18n', () => ({ useI18n: () => (key) => key }))
6868
// eslint-disable-next-line no-console
6969
jest.spyOn(console, 'warn').mockImplementation((warning) => warning.includes('[Vue warn]') ? null : console.log(warning));
7070

71-
jest.mock('@shell/composables/useI18n', () => ({ useI18n: () => (key) => key }));
71+
// jest.mock('@shell/composables/useI18n', () => ({ useI18n: () => (key) => key }));
72+
jest.mock('@shell/composables/useI18n', () => {
73+
return {
74+
useI18n() {
75+
return {
76+
t(key) {
77+
return key;
78+
}
79+
};
80+
}
81+
};
82+
});
7283
// eslint-disable-next-line no-console
7384
jest.spyOn(console, 'warn').mockImplementation((warning) => warning.includes('[Vue warn]') ? null : console.log(warning));
7485

shell/components/auth/__tests__/RoleDetailEdit.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ describe('component: RoleDetailEdit', () => {
5151
const wrapper = mount(RoleDetailEdit, {
5252
props: {
5353
value: {
54-
rules: [{ verbs }],
55-
subtype: 'GLOBAL'
54+
rules: [{ verbs }],
55+
subtype: 'GLOBAL',
56+
metadata: { name: 'global-role-with-inherited' },
5657
},
5758
},
5859

shell/components/form/ArrayList.vue

Lines changed: 66 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script>
2+
import { ref, watch, computed } from 'vue';
23
import debounce from 'lodash/debounce';
34
import { _EDIT, _VIEW } from '@shell/config/query-params';
45
import { removeAt } from '@shell/utils/array';
@@ -99,32 +100,85 @@ export default {
99100
default: '',
100101
},
101102
},
102-
data() {
103-
const input = (Array.isArray(this.value) ? this.value : []).slice();
104-
const rows = [];
103+
104+
setup(props, { emit }) {
105+
const input = (Array.isArray(props.value) ? props.value : []).slice();
106+
const rows = ref([]);
105107
106108
for ( const value of input ) {
107-
rows.push({ value });
109+
rows.value.push({ value });
108110
}
109-
if ( !rows.length && this.initialEmptyRow ) {
110-
const value = this.defaultAddValue ? clone(this.defaultAddValue) : '';
111+
if ( !rows.value.length && props.initialEmptyRow ) {
112+
const value = props.defaultAddValue ? clone(props.defaultAddValue) : '';
111113
112-
rows.push({ value });
114+
rows.value.push({ value });
113115
}
114116
115-
return { rows, lastUpdateWasFromValue: false };
117+
const isView = computed(() => {
118+
return props.mode === _VIEW;
119+
});
120+
121+
/**
122+
* Cleanup rows and emit input
123+
*/
124+
const update = () => {
125+
if ( isView.value ) {
126+
return;
127+
}
128+
const out = [];
129+
130+
for ( const row of rows.value ) {
131+
const trim = !props.valueMultiline && (typeof row.value === 'string');
132+
const value = trim ? row.value.trim() : row.value;
133+
134+
if ( typeof value !== 'undefined' ) {
135+
out.push(value);
136+
}
137+
}
138+
emit('update:value', out);
139+
};
140+
141+
const lastUpdateWasFromValue = ref(false);
142+
const queueUpdate = debounce(update, 50);
143+
144+
watch(
145+
rows,
146+
() => {
147+
// lastUpdateWasFromValue is used to break a cycle where when rows are updated
148+
// this was called which then forced rows to updated again
149+
if (!lastUpdateWasFromValue.value) {
150+
queueUpdate();
151+
}
152+
lastUpdateWasFromValue.value = false;
153+
},
154+
{ deep: true }
155+
);
156+
157+
watch(
158+
() => props.value,
159+
() => {
160+
lastUpdateWasFromValue.value = true;
161+
rows.value = (props.value || []).map((v) => ({ value: v }));
162+
},
163+
{ deep: true }
164+
);
165+
166+
return {
167+
rows,
168+
lastUpdateWasFromValue,
169+
queueUpdate,
170+
isView,
171+
update,
172+
};
116173
},
174+
117175
computed: {
118176
_addLabel() {
119177
return this.addLabel || this.t('generic.add');
120178
},
121179
_removeLabel() {
122180
return this.removeLabel || this.t('generic.remove');
123181
},
124-
125-
isView() {
126-
return this.mode === _VIEW;
127-
},
128182
showAdd() {
129183
return this.addAllowed;
130184
},
@@ -145,29 +199,7 @@ export default {
145199
return !this.valueMultiline && this.protip;
146200
}
147201
},
148-
watch: {
149-
value: {
150-
deep: true,
151-
handler() {
152-
this.lastUpdateWasFromValue = true;
153-
this.rows = (this.value || []).map((v) => ({ value: v }));
154-
}
155-
},
156-
157-
rows: {
158-
deep: true,
159-
handler(newValue, oldValue) {
160-
// lastUpdateWasFromValue is used to break a cycle where when rows are updated
161-
// this was called which then forced rows to updated again
162-
if (!this.lastUpdateWasFromValue) {
163-
this.queueUpdate();
164-
}
165-
this.lastUpdateWasFromValue = false;
166-
}
167-
}
168-
},
169202
created() {
170-
this.queueUpdate = debounce(this.update, 50);
171203
},
172204
methods: {
173205
add() {
@@ -193,26 +225,6 @@ export default {
193225
this.queueUpdate();
194226
},
195227
196-
/**
197-
* Cleanup rows and emit input
198-
*/
199-
update() {
200-
if ( this.isView ) {
201-
return;
202-
}
203-
const out = [];
204-
205-
for ( const row of this.rows ) {
206-
const trim = !this.valueMultiline && (typeof row.value === 'string');
207-
const value = trim ? row.value.trim() : row.value;
208-
209-
if ( typeof value !== 'undefined' ) {
210-
out.push(value);
211-
}
212-
}
213-
this.$emit('update:value', out);
214-
},
215-
216228
/**
217229
* Handle paste event, e.g. split multiple lines in rows
218230
*/

shell/components/form/Command.vue

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,14 @@ export default {
4343
},
4444
4545
data() {
46-
const {
47-
command,
48-
args,
49-
workingDir,
50-
stdin = false,
51-
stdinOnce = false,
52-
tty = false,
53-
} = this.value;
54-
5546
return {
56-
args,
57-
command,
47+
args: this.value.args,
48+
command: this.value.command,
5849
commandOptions: ['No', 'Once', 'Yes'],
59-
stdin,
60-
stdinOnce,
61-
tty,
62-
workingDir,
50+
stdin: this.value.stdin || false,
51+
stdinOnce: this.value.stdin || false,
52+
tty: this.value.tty || false,
53+
workingDir: this.value.workingDir,
6354
};
6455
},
6556

shell/components/form/EnvVars.vue

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,10 @@ export default {
3939
},
4040
4141
data() {
42-
const { env = [], envFrom = [] } = this.value;
43-
44-
const allEnv = [...env, ...envFrom].map((row) => {
45-
return { value: row, id: randomStr(4) };
46-
});
47-
4842
return {
49-
env, envFrom, allEnv
43+
env: [],
44+
envFrom: [],
45+
allEnv: [],
5046
};
5147
},
5248
@@ -63,7 +59,18 @@ export default {
6359
}
6460
}
6561
},
62+
6663
created() {
64+
const { env = [], envFrom = [] } = this.value;
65+
66+
const allEnv = [...env, ...envFrom].map((row) => {
67+
return { value: row, id: randomStr(4) };
68+
});
69+
70+
this.env = env;
71+
this.envFrom = envFrom;
72+
this.allEnv = allEnv;
73+
6774
this.queueUpdate = debounce(this.update, 500);
6875
},
6976

shell/components/form/HealthCheck.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ export default {
1818
},
1919
2020
data() {
21-
const { readinessProbe, livenessProbe, startupProbe } = this.value;
22-
2321
return {
24-
readinessProbe, livenessProbe, startupProbe
22+
readinessProbe: this.value.readinessProbe,
23+
livenessProbe: this.value.livenessProbe,
24+
startupProbe: this.value.startupProbe,
2525
};
2626
},
2727

shell/components/form/HookOption.vue

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,18 @@ export default {
2828
},
2929
3030
data() {
31-
const selectHook = null;
32-
33-
const defaultExec = { exec: { command: [] } };
34-
const defaultHttpGet = {
35-
httpGet: {
36-
host: '',
37-
path: '',
38-
port: null,
39-
scheme: '',
40-
httpHeaders: null
41-
}
42-
};
43-
4431
return {
45-
selectHook,
46-
defaultExec,
47-
defaultHttpGet,
32+
selectHook: null,
33+
defaultExec: { exec: { command: [] } },
34+
defaultHttpGet: {
35+
httpGet: {
36+
host: '',
37+
path: '',
38+
port: null,
39+
scheme: '',
40+
httpHeaders: null
41+
}
42+
},
4843
schemeOptions: ['HTTP', 'HTTPS']
4944
};
5045
},

shell/components/form/LifecycleHooks.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ export default {
2424
},
2525
2626
data() {
27-
const { postStart, preStop } = this.value;
28-
2927
return {
30-
postStart, preStop, hookOptions: ['postStart', 'preStop']
28+
postStart: this.value.postStart,
29+
preStop: this.value.preStop,
30+
hookOptions: ['postStart', 'preStop']
3131
};
3232
},
3333

shell/components/form/MatchExpressions.vue

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ export default {
7070
},
7171
7272
data() {
73+
return {
74+
ops: [],
75+
rules: [],
76+
custom: []
77+
};
78+
},
79+
80+
created() {
7381
const t = this.$store.getters['i18n/t'];
7482
7583
const podOptions = [
@@ -88,8 +96,6 @@ export default {
8896
{ label: t('workload.scheduling.affinity.matchExpressions.greaterThan'), value: 'Gt' },
8997
];
9098
91-
const ops = this.type === NODE ? nodeOptions : podOptions;
92-
9399
let rules;
94100
95101
// special case for matchFields and matchExpressions
@@ -127,11 +133,8 @@ export default {
127133
rules.push(newRule);
128134
}
129135
130-
return {
131-
ops,
132-
rules,
133-
custom: []
134-
};
136+
this.rules = rules;
137+
this.ops = this.type === NODE ? nodeOptions : podOptions;
135138
},
136139
137140
computed: {

0 commit comments

Comments
 (0)