@dative-gpi/foundation-shared-components 1.0.44 → 1.0.46
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/components/FSLoader.vue +1 -2
- package/components/FSSpan.vue +5 -0
- package/components/buttons/FSButtonDragIcon.vue +27 -0
- package/components/deviceOrganisations/FSStatusesRow.vue +1 -1
- package/components/deviceOrganisations/FSWorstAlert.vue +1 -1
- package/components/deviceOrganisations/FSWorstAlertCard.vue +1 -1
- package/components/fields/FSEntityFieldUI.vue +257 -0
- package/components/fields/FSSelectField.vue +0 -1
- package/components/fields/FSTermField.vue +1 -1
- package/components/fields/FSTextArea.vue +16 -3
- package/components/fields/FSTimeSlotField.vue +1 -1
- package/components/fields/FSTimeStepField.vue +3 -3
- package/components/fields/FSTranslateField.vue +1 -0
- package/components/fields/FSTranslateRichTextField.vue +1 -0
- package/components/fields/FSTranslateTextArea.vue +233 -0
- package/components/lists/FSDataTableUI.vue +3 -4
- package/components/lists/FSSimpleList.vue +133 -0
- package/components/map/FSMap.vue +2 -2
- package/components/selects/FSSelectAutoRefresh.vue +1 -1
- package/components/selects/FSSelectDashboardVariableType.vue +1 -1
- package/components/selects/FSSelectDateSetting.vue +1 -1
- package/components/selects/FSSelectDays.vue +1 -1
- package/components/selects/FSSelectListMode.vue +51 -0
- package/components/selects/FSSelectMonths.vue +1 -1
- package/components/tiles/FSTile.vue +90 -74
- package/models/deviceAlerts.ts +1 -1
- package/models/deviceConnectivities.ts +1 -1
- package/models/rules.ts +1 -1
- package/package.json +4 -4
- package/styles/components/fs_span.scss +2 -1
- package/styles/components/fs_text_area.scss +16 -1
- package/styles/components/fs_tile.scss +18 -6
- package/utils/statuses.ts +1 -1
- package/utils/time.ts +1 -1
package/components/FSLoader.vue
CHANGED
|
@@ -69,8 +69,7 @@ export default defineComponent({
|
|
|
69
69
|
case "text-h4" : return isMobileSized.value ? "16px" : "20px";
|
|
70
70
|
case "text-body" :
|
|
71
71
|
case "text-button" : return isMobileSized.value ? "14px" : "16px";
|
|
72
|
-
case "text-overline" :
|
|
73
|
-
case "text-overline": return "16px";
|
|
72
|
+
case "text-overline" : return "16px";
|
|
74
73
|
}
|
|
75
74
|
});
|
|
76
75
|
|
package/components/FSSpan.vue
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FSButton
|
|
3
|
+
icon="mdi-drag"
|
|
4
|
+
variant="icon"
|
|
5
|
+
v-bind="$attrs"
|
|
6
|
+
/>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script lang="ts">
|
|
10
|
+
import { defineComponent } from "vue";
|
|
11
|
+
|
|
12
|
+
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
13
|
+
|
|
14
|
+
import FSButton from "../FSButton.vue";
|
|
15
|
+
|
|
16
|
+
export default defineComponent({
|
|
17
|
+
name: "FSButtonCopyIcon",
|
|
18
|
+
components: {
|
|
19
|
+
FSButton
|
|
20
|
+
},
|
|
21
|
+
setup() {
|
|
22
|
+
return {
|
|
23
|
+
ColorEnum
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
</script>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
import { defineComponent, type PropType } from "vue";
|
|
31
31
|
|
|
32
32
|
import type { FSDeviceAlert, FSDeviceConnectivity, FSDeviceStatus, FSDeviceStatusGroup, FSModelStatus } from "@dative-gpi/foundation-shared-components/models";
|
|
33
|
-
import { ConnectivityStatus } from "@dative-gpi/foundation-shared-domain/
|
|
33
|
+
import { ConnectivityStatus } from "@dative-gpi/foundation-shared-domain/enums";
|
|
34
34
|
|
|
35
35
|
import FSConnectivity from "./FSConnectivity.vue";
|
|
36
36
|
import FSWorstAlert from "./FSWorstAlert.vue";
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<script lang="ts">
|
|
32
32
|
import { computed, defineComponent, type PropType, ref } from "vue";
|
|
33
33
|
|
|
34
|
-
import { AlertStatus, Criticity } from "@dative-gpi/foundation-shared-domain/
|
|
34
|
+
import { AlertStatus, Criticity } from "@dative-gpi/foundation-shared-domain/enums";
|
|
35
35
|
import type { FSDeviceAlert } from "@dative-gpi/foundation-shared-components/models";
|
|
36
36
|
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
37
37
|
|
|
@@ -60,7 +60,7 @@ import { computed, defineComponent, type PropType } from "vue";
|
|
|
60
60
|
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
61
61
|
import type { FSDeviceAlert} from "@dative-gpi/foundation-shared-components/models";
|
|
62
62
|
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
63
|
-
import { AlertStatus, Criticity } from "@dative-gpi/foundation-shared-domain/
|
|
63
|
+
import { AlertStatus, Criticity } from "@dative-gpi/foundation-shared-domain/enums";
|
|
64
64
|
import { useDateFormat } from "@dative-gpi/foundation-shared-services/composables";
|
|
65
65
|
|
|
66
66
|
import FSButton from "../FSButton.vue";
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FSBaseField
|
|
3
|
+
:description="$props.description"
|
|
4
|
+
:hideHeader="$props.hideHeader"
|
|
5
|
+
:required="$props.required"
|
|
6
|
+
:editable="$props.editable"
|
|
7
|
+
:label="$props.label"
|
|
8
|
+
:messages="messages"
|
|
9
|
+
>
|
|
10
|
+
<FSCol
|
|
11
|
+
gap="12px"
|
|
12
|
+
>
|
|
13
|
+
<FSRow>
|
|
14
|
+
<FSSelectField
|
|
15
|
+
:hideHeader="true"
|
|
16
|
+
:modelValue="$props.entityType"
|
|
17
|
+
@update:modelValue="$emit('update:entityType', $event)"
|
|
18
|
+
:items="actualEntityTypes"
|
|
19
|
+
:clearable="false"
|
|
20
|
+
/>
|
|
21
|
+
<template
|
|
22
|
+
v-if="itemsCount > 0"
|
|
23
|
+
>
|
|
24
|
+
<FSButton
|
|
25
|
+
:label="$tr('ui.entity-field.edit', 'Edit')"
|
|
26
|
+
icon="mdi-pencil"
|
|
27
|
+
@click="$emit('click:select')"
|
|
28
|
+
/>
|
|
29
|
+
</template>
|
|
30
|
+
<template
|
|
31
|
+
v-else
|
|
32
|
+
>
|
|
33
|
+
<FSButton
|
|
34
|
+
:label="$tr('ui.entity-field.select', 'Select')"
|
|
35
|
+
icon="mdi-plus-circle-multiple-outline"
|
|
36
|
+
@click="$emit('click:select')"
|
|
37
|
+
/>
|
|
38
|
+
</template>
|
|
39
|
+
</FSRow>
|
|
40
|
+
<FSRow>
|
|
41
|
+
<template
|
|
42
|
+
v-if="itemsCount > 0"
|
|
43
|
+
>
|
|
44
|
+
<FSColor
|
|
45
|
+
:color="ColorEnum.Primary"
|
|
46
|
+
:border="false"
|
|
47
|
+
width="100%"
|
|
48
|
+
>
|
|
49
|
+
<FSRow
|
|
50
|
+
padding="4px"
|
|
51
|
+
align="center-center"
|
|
52
|
+
>
|
|
53
|
+
<FSIcon
|
|
54
|
+
:icon="entityIcon"
|
|
55
|
+
/>
|
|
56
|
+
<FSSpan
|
|
57
|
+
font="text-overline"
|
|
58
|
+
>
|
|
59
|
+
{{ $tr('ui.entity-field.selected', '{0} selected(s)', itemsCount) }}
|
|
60
|
+
</FSSpan>
|
|
61
|
+
</FSRow>
|
|
62
|
+
</FSColor>
|
|
63
|
+
</template>
|
|
64
|
+
|
|
65
|
+
<template
|
|
66
|
+
v-else
|
|
67
|
+
>
|
|
68
|
+
<FSColor
|
|
69
|
+
:color="ColorEnum.Light"
|
|
70
|
+
:border="false"
|
|
71
|
+
width="100%"
|
|
72
|
+
>
|
|
73
|
+
<FSRow
|
|
74
|
+
padding="4px"
|
|
75
|
+
align="center-center"
|
|
76
|
+
>
|
|
77
|
+
<FSIcon
|
|
78
|
+
:icon="entityIcon"
|
|
79
|
+
/>
|
|
80
|
+
<FSSpan
|
|
81
|
+
font="text-overline"
|
|
82
|
+
>
|
|
83
|
+
{{ $tr('ui.entity-field.no-entity-selected', 'No entity selected') }}
|
|
84
|
+
</FSSpan>
|
|
85
|
+
</FSRow>
|
|
86
|
+
</FSColor>
|
|
87
|
+
</template>
|
|
88
|
+
</FSRow>
|
|
89
|
+
|
|
90
|
+
<FSFadeOut
|
|
91
|
+
v-if="$props.showEntities && itemsCount > 0"
|
|
92
|
+
maxHeight="220px"
|
|
93
|
+
width="100%"
|
|
94
|
+
>
|
|
95
|
+
<slot
|
|
96
|
+
name="items"
|
|
97
|
+
/>
|
|
98
|
+
</FSFadeOut>
|
|
99
|
+
</FSCol>
|
|
100
|
+
</FSBaseField>
|
|
101
|
+
</template>
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
<script lang="ts">
|
|
105
|
+
import { computed, defineComponent, type PropType } from "vue";
|
|
106
|
+
|
|
107
|
+
import { EntityType } from "@dative-gpi/foundation-shared-domain/enums";
|
|
108
|
+
import { ColorEnum } from "../../models";
|
|
109
|
+
import { useTranslations } from "@dative-gpi/bones-ui";
|
|
110
|
+
|
|
111
|
+
import FSRow from "../FSRow.vue";
|
|
112
|
+
import FSCol from "../FSCol.vue";
|
|
113
|
+
import FSBaseField from "./FSBaseField.vue";
|
|
114
|
+
import FSSelectField from "./FSSelectField.vue";
|
|
115
|
+
import FSButton from "../FSButton.vue";
|
|
116
|
+
import FSIcon from "../FSIcon.vue";
|
|
117
|
+
import FSColor from "../FSColor.vue";
|
|
118
|
+
|
|
119
|
+
export default defineComponent({
|
|
120
|
+
name: "FSEntityFieldUI",
|
|
121
|
+
components: {
|
|
122
|
+
FSBaseField,
|
|
123
|
+
FSSelectField,
|
|
124
|
+
FSButton,
|
|
125
|
+
FSIcon,
|
|
126
|
+
FSColor,
|
|
127
|
+
FSRow,
|
|
128
|
+
FSCol
|
|
129
|
+
},
|
|
130
|
+
props: {
|
|
131
|
+
label: {
|
|
132
|
+
type: String as PropType<string | null>,
|
|
133
|
+
required: false,
|
|
134
|
+
default: null
|
|
135
|
+
},
|
|
136
|
+
description: {
|
|
137
|
+
type: String as PropType<string | null>,
|
|
138
|
+
required: false,
|
|
139
|
+
default: null
|
|
140
|
+
},
|
|
141
|
+
itemsCount: {
|
|
142
|
+
type: Number,
|
|
143
|
+
required: false,
|
|
144
|
+
default: 0
|
|
145
|
+
},
|
|
146
|
+
hideHeader: {
|
|
147
|
+
type: Boolean,
|
|
148
|
+
required: false,
|
|
149
|
+
default: false
|
|
150
|
+
},
|
|
151
|
+
required: {
|
|
152
|
+
type: Boolean,
|
|
153
|
+
required: false,
|
|
154
|
+
default: false
|
|
155
|
+
},
|
|
156
|
+
rules: {
|
|
157
|
+
type: Array as PropType<any[]>,
|
|
158
|
+
required: false,
|
|
159
|
+
default: () => []
|
|
160
|
+
},
|
|
161
|
+
messages: {
|
|
162
|
+
type: Array as PropType<string[]>,
|
|
163
|
+
required: false,
|
|
164
|
+
default: null
|
|
165
|
+
},
|
|
166
|
+
editable: {
|
|
167
|
+
type: Boolean,
|
|
168
|
+
required: false,
|
|
169
|
+
default: true
|
|
170
|
+
},
|
|
171
|
+
entityType: {
|
|
172
|
+
type: Number as PropType<EntityType>,
|
|
173
|
+
required: true
|
|
174
|
+
},
|
|
175
|
+
allowedEntityTypes: {
|
|
176
|
+
type: Array as PropType<EntityType[]>,
|
|
177
|
+
required: false,
|
|
178
|
+
default: () => []
|
|
179
|
+
},
|
|
180
|
+
showEntities: {
|
|
181
|
+
type: Boolean,
|
|
182
|
+
required: false,
|
|
183
|
+
default: true
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
emits: ["update:entityType", "click:select"],
|
|
187
|
+
setup(props) {
|
|
188
|
+
const { $tr } = useTranslations();
|
|
189
|
+
|
|
190
|
+
const actualEntityTypes = computed(() => {
|
|
191
|
+
const items = [
|
|
192
|
+
{
|
|
193
|
+
id: EntityType.Model,
|
|
194
|
+
label: $tr("ui.entity-type.models", "Models")
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: EntityType.Group,
|
|
198
|
+
label: $tr("ui.entity-type.groups", "Groups")
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
id: EntityType.Location,
|
|
202
|
+
label: $tr("ui.entity-type.locations", "Locations")
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: EntityType.Device,
|
|
206
|
+
label: $tr("ui.entity-type.devices", "Devices")
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
id: EntityType.User,
|
|
210
|
+
label: $tr("ui.entity-type.users", "Users")
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: EntityType.Dashboard,
|
|
214
|
+
label: $tr("ui.entity-type.dashboards", "Dashboards")
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
id: EntityType.Folder,
|
|
218
|
+
label: $tr("ui.entity-type.folders", "Folders")
|
|
219
|
+
}
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
if(props.allowedEntityTypes.length) {
|
|
223
|
+
return items.filter(item => props.allowedEntityTypes.includes(item.id));
|
|
224
|
+
} else {
|
|
225
|
+
return items;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const entityIcon = computed(() => {
|
|
230
|
+
switch(props.entityType) {
|
|
231
|
+
case EntityType.Model:
|
|
232
|
+
return "mdi-cube";
|
|
233
|
+
case EntityType.Group:
|
|
234
|
+
return "mdi-account-group";
|
|
235
|
+
case EntityType.Location:
|
|
236
|
+
return "mdi-map-marker";
|
|
237
|
+
case EntityType.Device:
|
|
238
|
+
return "mdi-cellphone";
|
|
239
|
+
case EntityType.User:
|
|
240
|
+
return "mdi-account";
|
|
241
|
+
case EntityType.Dashboard:
|
|
242
|
+
return "mdi-view-dashboard";
|
|
243
|
+
case EntityType.Folder:
|
|
244
|
+
return "mdi-folder";
|
|
245
|
+
default:
|
|
246
|
+
return "mdi-cube";
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
ColorEnum,
|
|
252
|
+
entityIcon,
|
|
253
|
+
actualEntityTypes
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
</script>
|
|
@@ -83,7 +83,7 @@ import _ from "lodash";
|
|
|
83
83
|
import { DateRules, NumberRules, TextRules } from "@dative-gpi/foundation-shared-components/models";
|
|
84
84
|
import { useDateFormat } from "@dative-gpi/foundation-shared-services/composables";
|
|
85
85
|
import { useRules } from "@dative-gpi/foundation-shared-components/composables";
|
|
86
|
-
import { DateSetting } from "@dative-gpi/foundation-shared-domain/
|
|
86
|
+
import { DateSetting } from "@dative-gpi/foundation-shared-domain/enums";
|
|
87
87
|
|
|
88
88
|
import FSSelectDateSetting from "../selects/FSSelectDateSetting.vue";
|
|
89
89
|
import FSDateTimeRangeField from "./FSDateTimeRangeField.vue";
|
|
@@ -7,6 +7,15 @@
|
|
|
7
7
|
:editable="$props.editable"
|
|
8
8
|
:messages="messages"
|
|
9
9
|
>
|
|
10
|
+
<template
|
|
11
|
+
v-if="$slots.label"
|
|
12
|
+
v-slot:label="slotData"
|
|
13
|
+
>
|
|
14
|
+
<slot
|
|
15
|
+
name="label"
|
|
16
|
+
v-bind="slotData"
|
|
17
|
+
/>
|
|
18
|
+
</template>
|
|
10
19
|
<v-textarea
|
|
11
20
|
class="fs-text-area"
|
|
12
21
|
variant="outlined"
|
|
@@ -26,7 +35,7 @@
|
|
|
26
35
|
v-bind="$attrs"
|
|
27
36
|
>
|
|
28
37
|
<template
|
|
29
|
-
v-for="(_, name) in
|
|
38
|
+
v-for="(_, name) in slots"
|
|
30
39
|
v-slot:[name]="slotData"
|
|
31
40
|
>
|
|
32
41
|
<slot
|
|
@@ -56,7 +65,7 @@
|
|
|
56
65
|
<script lang="ts">
|
|
57
66
|
import { computed, defineComponent, type PropType, type StyleValue } from "vue";
|
|
58
67
|
|
|
59
|
-
import { useColors, useBreakpoints, useRules } from "@dative-gpi/foundation-shared-components/composables";
|
|
68
|
+
import { useColors, useBreakpoints, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
|
|
60
69
|
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
61
70
|
|
|
62
71
|
import FSBaseField from "./FSBaseField.vue";
|
|
@@ -130,6 +139,9 @@ export default defineComponent({
|
|
|
130
139
|
const { validateOn, getMessages } = useRules();
|
|
131
140
|
const { isMobileSized } = useBreakpoints();
|
|
132
141
|
const { getColors } = useColors();
|
|
142
|
+
const { slots } = useSlots();
|
|
143
|
+
|
|
144
|
+
delete slots.label;
|
|
133
145
|
|
|
134
146
|
const errors = getColors(ColorEnum.Error);
|
|
135
147
|
const lights = getColors(ColorEnum.Light);
|
|
@@ -185,7 +197,8 @@ export default defineComponent({
|
|
|
185
197
|
ColorEnum,
|
|
186
198
|
messages,
|
|
187
199
|
classes,
|
|
188
|
-
style
|
|
200
|
+
style,
|
|
201
|
+
slots
|
|
189
202
|
};
|
|
190
203
|
}
|
|
191
204
|
});
|
|
@@ -65,7 +65,7 @@ import { computed, defineComponent, type PropType, type StyleValue } from "vue";
|
|
|
65
65
|
|
|
66
66
|
import { useColors, useRules } from "@dative-gpi/foundation-shared-components/composables";
|
|
67
67
|
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
68
|
-
import { Days } from "@dative-gpi/foundation-shared-domain/
|
|
68
|
+
import { Days } from "@dative-gpi/foundation-shared-domain/enums";
|
|
69
69
|
|
|
70
70
|
import FSSelectField from "./FSSelectField.vue";
|
|
71
71
|
import FSBaseField from "./FSBaseField.vue";
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
<script lang="ts">
|
|
56
56
|
import { computed, defineComponent, type PropType } from "vue";
|
|
57
57
|
|
|
58
|
-
import type { TimeUnit } from "@dative-gpi/foundation-shared-domain/
|
|
58
|
+
import type { TimeUnit } from "@dative-gpi/foundation-shared-domain/enums";
|
|
59
59
|
|
|
60
60
|
import { useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
|
|
61
61
|
import { timeSteps } from "@dative-gpi/foundation-shared-components/utils";
|
|
@@ -131,14 +131,14 @@ export default defineComponent({
|
|
|
131
131
|
return Object.keys(slots).filter(k => k.startsWith("number-")).reduce((acc, key) => {
|
|
132
132
|
acc[key.substring("number-".length)] = slots[key];
|
|
133
133
|
return acc;
|
|
134
|
-
}, {});
|
|
134
|
+
}, {} as {[index: string]: any});
|
|
135
135
|
});
|
|
136
136
|
|
|
137
137
|
const selectSlots = computed((): any => {
|
|
138
138
|
return Object.keys(slots).filter(k => k.startsWith("select-")).reduce((acc, key) => {
|
|
139
139
|
acc[key.substring("select-".length)] = slots[key];
|
|
140
140
|
return acc;
|
|
141
|
-
}, {});
|
|
141
|
+
}, {} as {[index: string]: any});
|
|
142
142
|
});
|
|
143
143
|
|
|
144
144
|
const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FSTextArea
|
|
3
|
+
:editable="$props.editable"
|
|
4
|
+
:modelValue="$props.modelValue"
|
|
5
|
+
@update:modelValue="$emit('update:modelValue', $event)"
|
|
6
|
+
v-bind="$attrs"
|
|
7
|
+
>
|
|
8
|
+
<template
|
|
9
|
+
v-for="(_, name) in $slots"
|
|
10
|
+
v-slot:[name]="slotData"
|
|
11
|
+
>
|
|
12
|
+
<slot
|
|
13
|
+
:name="name"
|
|
14
|
+
v-bind="slotData"
|
|
15
|
+
/>
|
|
16
|
+
</template>
|
|
17
|
+
<template
|
|
18
|
+
#append
|
|
19
|
+
>
|
|
20
|
+
<FSButton
|
|
21
|
+
height="100%"
|
|
22
|
+
style=""
|
|
23
|
+
:prependIcon="$props.buttonPrependIcon"
|
|
24
|
+
:appendIcon="$props.buttonAppendIcon"
|
|
25
|
+
:variant="$props.buttonVariant"
|
|
26
|
+
:color="$props.buttonColor"
|
|
27
|
+
@click="dialog = true"
|
|
28
|
+
/>
|
|
29
|
+
<slot
|
|
30
|
+
name="append"
|
|
31
|
+
/>
|
|
32
|
+
</template>
|
|
33
|
+
</FSTextArea>
|
|
34
|
+
<FSDialogSubmit
|
|
35
|
+
:title="$tr('ui.translate-text-area.title', 'Handle translations')"
|
|
36
|
+
:submitButtonColor="$props.buttonColor"
|
|
37
|
+
@click:submitButton="onSubmit"
|
|
38
|
+
v-model="dialog"
|
|
39
|
+
>
|
|
40
|
+
<template
|
|
41
|
+
#body
|
|
42
|
+
>
|
|
43
|
+
<FSCol
|
|
44
|
+
gap="32px"
|
|
45
|
+
>
|
|
46
|
+
<FSTextArea
|
|
47
|
+
:label="$tr('ui.translate-text-area.default-value', 'Default value')"
|
|
48
|
+
:editable="false"
|
|
49
|
+
:rows="($attrs.rows as number)"
|
|
50
|
+
:modelValue="$props.modelValue"
|
|
51
|
+
/>
|
|
52
|
+
<FSCol
|
|
53
|
+
gap="20px"
|
|
54
|
+
>
|
|
55
|
+
<FSTextArea
|
|
56
|
+
v-for="(language, index) in languages"
|
|
57
|
+
:editable="$props.editable"
|
|
58
|
+
:key="index"
|
|
59
|
+
:modelValue="getTranslation(language.code)"
|
|
60
|
+
:rows="($attrs.rows as number)"
|
|
61
|
+
@update:modelValue="setTranslation(language.code, $event)"
|
|
62
|
+
>
|
|
63
|
+
<template
|
|
64
|
+
#label
|
|
65
|
+
>
|
|
66
|
+
<FSRow
|
|
67
|
+
:wrap="false"
|
|
68
|
+
align="center-left"
|
|
69
|
+
>
|
|
70
|
+
<FSSpan
|
|
71
|
+
font="text-overline"
|
|
72
|
+
:style="style"
|
|
73
|
+
>
|
|
74
|
+
{{ $tr("ui.translate-field.translate-in", "Translate in {0}", language.label) }}
|
|
75
|
+
</FSSpan>
|
|
76
|
+
<FSIcon>
|
|
77
|
+
{{ language.icon }}
|
|
78
|
+
</FSIcon>
|
|
79
|
+
</FSRow>
|
|
80
|
+
</template>
|
|
81
|
+
</FSTextArea>
|
|
82
|
+
</FSCol>
|
|
83
|
+
</FSCol>
|
|
84
|
+
</template>
|
|
85
|
+
</FSDialogSubmit>
|
|
86
|
+
</template>
|
|
87
|
+
|
|
88
|
+
<script lang="ts">
|
|
89
|
+
import { computed, defineComponent, type PropType, ref, type StyleValue } from "vue";
|
|
90
|
+
|
|
91
|
+
import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
92
|
+
import { useAppLanguages } from "@dative-gpi/foundation-shared-services/composables";
|
|
93
|
+
|
|
94
|
+
import { useColors } from "../../composables";
|
|
95
|
+
|
|
96
|
+
import FSDialogSubmit from "../FSDialogSubmit.vue";
|
|
97
|
+
import FSTextArea from "./FSTextArea.vue";
|
|
98
|
+
import FSButton from "../FSButton.vue";
|
|
99
|
+
import FSIcon from "../FSIcon.vue";
|
|
100
|
+
import FSSpan from "../FSSpan.vue";
|
|
101
|
+
import FSRow from "../FSRow.vue";
|
|
102
|
+
|
|
103
|
+
export default defineComponent({
|
|
104
|
+
name: "FSTranslateTextArea",
|
|
105
|
+
components: {
|
|
106
|
+
FSDialogSubmit,
|
|
107
|
+
FSTextArea,
|
|
108
|
+
FSButton,
|
|
109
|
+
FSIcon,
|
|
110
|
+
FSSpan,
|
|
111
|
+
FSRow
|
|
112
|
+
},
|
|
113
|
+
props: {
|
|
114
|
+
buttonPrependIcon: {
|
|
115
|
+
type: String as PropType<string | null>,
|
|
116
|
+
required: false,
|
|
117
|
+
default: "mdi-translate"
|
|
118
|
+
},
|
|
119
|
+
buttonLabel: {
|
|
120
|
+
type: String as PropType<string | null>,
|
|
121
|
+
required: false,
|
|
122
|
+
default: null
|
|
123
|
+
},
|
|
124
|
+
buttonAppendIcon: {
|
|
125
|
+
type: String as PropType<string | null>,
|
|
126
|
+
required: false,
|
|
127
|
+
default: null
|
|
128
|
+
},
|
|
129
|
+
buttonVariant: {
|
|
130
|
+
type: String as PropType<"standard" | "full" | "icon">,
|
|
131
|
+
required: false,
|
|
132
|
+
default: "standard"
|
|
133
|
+
},
|
|
134
|
+
modelValue: {
|
|
135
|
+
type: String as PropType<string | null>,
|
|
136
|
+
required: false,
|
|
137
|
+
default: null
|
|
138
|
+
},
|
|
139
|
+
property: {
|
|
140
|
+
type: String as PropType<string>,
|
|
141
|
+
required: false,
|
|
142
|
+
default: "label"
|
|
143
|
+
},
|
|
144
|
+
translations: {
|
|
145
|
+
type: Array as PropType<{ languageCode: string; [key: string]: string }[]>,
|
|
146
|
+
required: false,
|
|
147
|
+
default: () => []
|
|
148
|
+
},
|
|
149
|
+
buttonColor: {
|
|
150
|
+
type: String as PropType<ColorBase>,
|
|
151
|
+
required: false,
|
|
152
|
+
default: ColorEnum.Primary
|
|
153
|
+
},
|
|
154
|
+
editable: {
|
|
155
|
+
type: Boolean,
|
|
156
|
+
required: false,
|
|
157
|
+
default: true
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
emits: ["update:modelValue", "update:translations"],
|
|
161
|
+
setup(props, { emit }) {
|
|
162
|
+
const { languages } = useAppLanguages();
|
|
163
|
+
const { getColors } = useColors();
|
|
164
|
+
|
|
165
|
+
const dialog = ref(false);
|
|
166
|
+
|
|
167
|
+
const innerTranslations = ref(props.translations);
|
|
168
|
+
|
|
169
|
+
const lights = getColors(ColorEnum.Light);
|
|
170
|
+
const darks = getColors(ColorEnum.Dark);
|
|
171
|
+
|
|
172
|
+
const style = computed((): StyleValue => {
|
|
173
|
+
if (!props.editable) {
|
|
174
|
+
return {
|
|
175
|
+
"--fs-translate-field-color": lights.dark
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
"--fs-translate-field-color": darks.base
|
|
180
|
+
};
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const getTranslation = (languageCode: string): string => {
|
|
184
|
+
if (!innerTranslations.value) {
|
|
185
|
+
return "";
|
|
186
|
+
}
|
|
187
|
+
const translation = innerTranslations.value.find((t) => t.languageCode === languageCode);
|
|
188
|
+
if (!translation || !translation[props.property]) {
|
|
189
|
+
return "";
|
|
190
|
+
}
|
|
191
|
+
return translation[props.property];
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const setTranslation = (languageCode: string, value: string): void => {
|
|
195
|
+
if (!innerTranslations.value) {
|
|
196
|
+
innerTranslations.value = [{
|
|
197
|
+
languageCode,
|
|
198
|
+
[props.property]: value
|
|
199
|
+
}]
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const translation = innerTranslations.value.find((t) => t.languageCode === languageCode);
|
|
203
|
+
if (translation) {
|
|
204
|
+
translation[props.property] = value;
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
innerTranslations.value.push({
|
|
208
|
+
languageCode,
|
|
209
|
+
[props.property]: value
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const onSubmit = (): void => {
|
|
215
|
+
dialog.value = false;
|
|
216
|
+
if (props.editable) {
|
|
217
|
+
emit("update:translations", innerTranslations.value);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
innerTranslations,
|
|
223
|
+
ColorEnum,
|
|
224
|
+
languages,
|
|
225
|
+
dialog,
|
|
226
|
+
style,
|
|
227
|
+
getTranslation,
|
|
228
|
+
setTranslation,
|
|
229
|
+
onSubmit
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
</script>
|