Skip to content

Commit 7276818

Browse files
committed
Refactor code to use optional chaining for accessing nested properties
1 parent 6a7d195 commit 7276818

File tree

3 files changed

+203
-9
lines changed

3 files changed

+203
-9
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<template lang="pug">
2+
//control-wrapper(v-bind="controlWrapper" :styles="styles" :isFocused="isFocused" :appliedOptions="appliedOptions")
3+
div
4+
q-select(
5+
:model-value="control.data"
6+
:options="suggestions"
7+
:input-debounce="0"
8+
fill-input
9+
:use-input="suggestions.length === 0"
10+
use-chips
11+
:id="control.id + '-input'"
12+
:disable="!control.enabled"
13+
:placeholder="appliedOptions.placeholder"
14+
:label="computedLabel"
15+
:hint="control.description"
16+
:error="control.errors !== ''"
17+
:error-message="control.errors"
18+
:clearable="true"
19+
:hide-dropdown-icon="suggestions.length === 0"
20+
@update:model-value="onChange"
21+
@focus="isFocused = true"
22+
@blur="isFocused = false"
23+
@new-value="createValue"
24+
filled multiple
25+
)
26+
//- q-input(
27+
//- v-else
28+
//- :id="control.id + '-input'"
29+
//- :disable="!control.enabled"
30+
//- :placeholder="appliedOptions.placeholder"
31+
//- :label="computedLabel"
32+
//- :hint="control.description"
33+
//- :error="control.errors !== ''"
34+
//- :error-message="control.errors"
35+
//- :model-value="control.data"
36+
//- :maxlength="appliedOptions.restrict ? control.schema.maxLength : undefined"
37+
//- :clearable="true"
38+
//- @update:model-value="onChange"
39+
//- @focus="isFocused = true"
40+
//- @blur="isFocused = false"
41+
//- filled
42+
//- )
43+
</template>
44+
45+
<script lang="ts">
46+
import { defineComponent } from 'vue';
47+
import { rendererProps, useJsonFormsControl } from '@jsonforms/vue';
48+
import {
49+
isControl,
50+
isStringControl,
51+
rankWith,
52+
} from '@jsonforms/core';
53+
import type { JsonFormsRendererRegistryEntry } from '@jsonforms/core';
54+
import { isArray, isObject, isString, iterate } from 'radash';
55+
import type { RendererProps } from '@jsonforms/vue';
56+
import type { ControlElement } from '@jsonforms/core';
57+
import { useQuasarControl } from '../util';
58+
import { ControlWrapper } from '@jsonforms/vue-vanilla';
59+
60+
const QStringControlRenderer = defineComponent({
61+
name: 'q-string-control-renderer',
62+
components: {
63+
ControlWrapper,
64+
},
65+
props: {
66+
...rendererProps<ControlElement>(),
67+
},
68+
setup(props: RendererProps<ControlElement>) {
69+
return useQuasarControl(
70+
useJsonFormsControl(props),
71+
(value) => isObject(value) ? value.value : value || undefined
72+
)
73+
},
74+
methods: {
75+
createValue(val, done) {
76+
done(val, 'add-unique')
77+
},
78+
isIterable(obj) {
79+
// checks for null and undefined
80+
if (obj == null) {
81+
return false;
82+
}
83+
return typeof obj[Symbol.iterator] === 'function';
84+
}
85+
},
86+
computed: {
87+
suggestions() {
88+
const suggestions = this.control.uischema.options?.suggestion;
89+
90+
let everyString = false
91+
if (this.isIterable(suggestions) && suggestions.length > 0) {
92+
for (const suggestion of suggestions) {
93+
if (typeof suggestion !== 'string') {
94+
everyString = false
95+
break
96+
}
97+
everyString = true
98+
}
99+
}
100+
101+
if (
102+
suggestions === undefined ||
103+
!isArray(suggestions) ||
104+
!everyString
105+
) {
106+
// check for incorrect data
107+
return [];
108+
}
109+
return suggestions;
110+
},
111+
computedLabel() {
112+
return this.control.label === undefined ? this.control.schema.title : this.control.label;
113+
},
114+
},
115+
});
116+
export default QStringControlRenderer;
117+
118+
</script>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<template lang="pug">
2+
div password
3+
//- <!-- <control-wrapper v-bind="controlWrapper" :styles="styles" :isFocused="isFocused" :appliedOptions="appliedOptions">
4+
//- <v-text-field :type="passwordVisible ? 'text' : 'password'"
5+
//- :append-icon="passwordVisible ? 'mdi-eye' : 'mdi-eye-off'"
6+
//- @click:append="() => (passwordVisible = !passwordVisible)" :id="control.id + '-input'"
7+
//- :class="styles.control.input" :disabled="!control.enabled" :autofocus="appliedOptions.focus"
8+
//- :placeholder="appliedOptions.placeholder" :label="computedLabel" :hint="control.description"
9+
//- :persistent-hint="persistentHint()" :required="control.required" :error-messages="control.errors"
10+
//- :model-value="control.data" :maxlength="appliedOptions.restrict ? control.schema.maxLength : undefined
11+
//- " :size="appliedOptions.trim && control.schema.maxLength !== undefined
12+
//- ? control.schema.maxLength
13+
//- : undefined
14+
//- " v-bind="vuetifyProps('v-text-field')" @update:model-value="onChange" @focus="handleFocus" @blur="handleBlur" />
15+
//- </control-wrapper> -->
16+
</template>
17+
18+
<script lang="ts">
19+
import {
20+
// ControlElement,
21+
// JsonFormsRendererRegistryEntry,
22+
rankWith,
23+
isStringControl,
24+
and,
25+
formatIs,
26+
} from '@jsonforms/core';
27+
import { defineComponent, ref } from 'vue';
28+
import {
29+
rendererProps,
30+
useJsonFormsControl,
31+
// RendererProps,
32+
} from '@jsonforms/vue';
33+
import { default as ControlWrapper } from './ControlWrapper.vue';
34+
35+
const controlRenderer = defineComponent({
36+
name: 'password-control-renderer',
37+
components: {
38+
ControlWrapper,
39+
// VTextField,
40+
},
41+
props: {
42+
...rendererProps<ControlElement>(),
43+
},
44+
setup(props: RendererProps<ControlElement>) {
45+
const passwordVisible = ref(false);
46+
47+
return {
48+
// ...useVuetifyControl(
49+
// useJsonFormsControl(props),
50+
// (value) => value || undefined,
51+
// 300
52+
// ),
53+
passwordVisible,
54+
};
55+
},
56+
});
57+
58+
export default controlRenderer;
59+
60+
export const entry: JsonFormsRendererRegistryEntry = {
61+
renderer: controlRenderer,
62+
tester: rankWith(2, and(isStringControl, formatIs('password'))),
63+
};
64+
</script>
Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
11
import QStringControlRenderer from "./QStringControlRenderer.vue";
2+
import QArrayControlRenderer from "./QArrayControlRenderer.vue";
23
import QDateControlRenderer from "./QDateControlRenderer.vue";
34
import QNumberControlRenderer from "./QNumberControlRenderer.vue";
4-
import { isControl, isDateControl, isNumberControl, rankWith, type JsonFormsRendererRegistryEntry } from "@jsonforms/core";
5+
import QPasswordControlRenderer from "./QPasswordControlRenderer.vue";
6+
import { isControl, isDateControl, isNumberControl, isPrimitiveArrayControl, rankWith, type JsonFormsRendererRegistryEntry } from "@jsonforms/core";
57

68
const QDateControlRendererEntry: JsonFormsRendererRegistryEntry = {
7-
renderer: QDateControlRenderer,
8-
tester: rankWith(2, isDateControl),
9+
renderer: QDateControlRenderer,
10+
tester: rankWith(2, isDateControl),
911
};
1012

1113
const QNumberControlRendererEntry: JsonFormsRendererRegistryEntry = {
12-
renderer: QNumberControlRenderer,
13-
tester: rankWith(1, isNumberControl),
14+
renderer: QNumberControlRenderer,
15+
tester: rankWith(1, isNumberControl),
1416
};
1517

16-
1718
export const QStringControlRendererEntry: JsonFormsRendererRegistryEntry = {
1819
renderer: QStringControlRenderer,
1920
tester: rankWith(1, isControl),
2021
};
2122

23+
export const QArrayControlRendererEntry: JsonFormsRendererRegistryEntry = {
24+
renderer: QArrayControlRenderer,
25+
tester: rankWith(2, isPrimitiveArrayControl),
26+
};
27+
28+
export const QPasswordControlRendererEntry: JsonFormsRendererRegistryEntry = {
29+
renderer: QPasswordControlRenderer,
30+
tester: rankWith(2, isControl),
31+
};
32+
2233
export const ControlsRenderer = [
23-
QDateControlRendererEntry,
24-
QNumberControlRendererEntry,
25-
QStringControlRendererEntry,
34+
QDateControlRendererEntry,
35+
QNumberControlRendererEntry,
36+
QStringControlRendererEntry,
37+
QArrayControlRendererEntry,
2638
];

0 commit comments

Comments
 (0)