@dative-gpi/foundation-shared-components 1.0.194-dynamic-v-node → 1.0.194-playlists-02
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.
|
@@ -28,10 +28,18 @@ export default defineComponent({
|
|
|
28
28
|
type: Boolean,
|
|
29
29
|
required: false,
|
|
30
30
|
default: true
|
|
31
|
+
},
|
|
32
|
+
variant: {
|
|
33
|
+
type: String as () => "fill" | "outline",
|
|
34
|
+
required: false,
|
|
35
|
+
default: "outline"
|
|
31
36
|
}
|
|
32
37
|
},
|
|
33
38
|
setup(props) {
|
|
34
39
|
const icon = computed((): string => {
|
|
40
|
+
if (props.variant === "fill") {
|
|
41
|
+
return props.value ? "mdi-check-circle" : "mdi-close-circle";
|
|
42
|
+
}
|
|
35
43
|
return props.value ? "mdi-check-circle-outline" : "mdi-close-circle-outline";
|
|
36
44
|
});
|
|
37
45
|
|
|
@@ -2,12 +2,21 @@
|
|
|
2
2
|
<FSCol
|
|
3
3
|
gap="12px"
|
|
4
4
|
>
|
|
5
|
-
<
|
|
6
|
-
v-if="$props.searchable"
|
|
7
|
-
:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
<FSRow
|
|
6
|
+
v-if="$props.searchable || $slots.action"
|
|
7
|
+
:wrap="false"
|
|
8
|
+
align="center-left"
|
|
9
|
+
>
|
|
10
|
+
<FSSearchField
|
|
11
|
+
v-if="$props.searchable"
|
|
12
|
+
:hideHeader="true"
|
|
13
|
+
:modelValue="actualSearch"
|
|
14
|
+
@update:modelValue="onSearch"
|
|
15
|
+
/>
|
|
16
|
+
<slot
|
|
17
|
+
name="action"
|
|
18
|
+
/>
|
|
19
|
+
</FSRow>
|
|
11
20
|
<FSFadeOut
|
|
12
21
|
v-if="$props.direction == ListDirections.Column"
|
|
13
22
|
:maxHeight="$props.maxHeight"
|
|
@@ -109,11 +118,13 @@ import FSFadeOut from "../FSFadeOut.vue";
|
|
|
109
118
|
import FSSlideGroup from "../FSSlideGroup.vue"
|
|
110
119
|
import FSSearchField from "../fields/FSSearchField.vue";
|
|
111
120
|
import FSSimpleTileUI from "../tiles/FSSimpleTileUI.vue";
|
|
121
|
+
import FSRow from "../FSRow.vue";
|
|
112
122
|
|
|
113
123
|
export default defineComponent({
|
|
114
124
|
name: "FSTileList",
|
|
115
125
|
components: {
|
|
116
126
|
FSCol,
|
|
127
|
+
FSRow,
|
|
117
128
|
FSFadeOut,
|
|
118
129
|
FSLoader,
|
|
119
130
|
FSSlideGroup,
|
|
@@ -223,6 +234,12 @@ export default defineComponent({
|
|
|
223
234
|
actualSearch.value = value;
|
|
224
235
|
});
|
|
225
236
|
|
|
237
|
+
watch(() => props.singleSelect, () => {
|
|
238
|
+
if(props.singleSelect && props.modelValue.length > 1) {
|
|
239
|
+
emit("update:modelValue", []);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
226
243
|
return {
|
|
227
244
|
actualSearch,
|
|
228
245
|
filteredItems,
|
|
@@ -47,30 +47,26 @@ export default {
|
|
|
47
47
|
to: {
|
|
48
48
|
type: Object as PropType<RouteLocation | null>,
|
|
49
49
|
required: false
|
|
50
|
-
},
|
|
51
|
-
html: {
|
|
52
|
-
type: String,
|
|
53
|
-
required: false
|
|
54
50
|
}
|
|
55
51
|
},
|
|
56
52
|
emits: ['click', 'auxclick'],
|
|
57
53
|
setup(props, { emit }) {
|
|
58
54
|
const map = inject<Ref<Map | null>>(MAP);
|
|
59
55
|
const markerClusterGroup = inject<Ref<MarkerClusterGroup | null>>(MARKERCLUSTERGROUP, ref(null));
|
|
60
|
-
|
|
56
|
+
|
|
61
57
|
const { getColors } = useColors();
|
|
62
58
|
const { handleRoutingEvent } = useRouting();
|
|
63
59
|
|
|
64
|
-
if
|
|
60
|
+
if(!map) {
|
|
65
61
|
throw new Error('FSMapTileLayer must be used inside a FSMap component');
|
|
66
62
|
}
|
|
67
63
|
|
|
68
|
-
if
|
|
64
|
+
if(!map.value) {
|
|
69
65
|
throw new Error('FSMapTileLayer must be used inside a FSMap component with a map');
|
|
70
66
|
}
|
|
71
|
-
|
|
67
|
+
|
|
72
68
|
const getMarkerIcon = () => {
|
|
73
|
-
if
|
|
69
|
+
if(props.variant === 'gps') {
|
|
74
70
|
const size = 16;
|
|
75
71
|
return divIcon({
|
|
76
72
|
html: gpsMarkerHtml(),
|
|
@@ -80,7 +76,7 @@ export default {
|
|
|
80
76
|
});
|
|
81
77
|
}
|
|
82
78
|
|
|
83
|
-
if
|
|
79
|
+
if(props.variant === 'location') {
|
|
84
80
|
const size = 36;
|
|
85
81
|
return divIcon({
|
|
86
82
|
html: locationMarkerHtml(props.icon ?? "mdi-map-marker", getColors(props.color).base, props.label),
|
|
@@ -92,7 +88,7 @@ export default {
|
|
|
92
88
|
|
|
93
89
|
const size = 16;
|
|
94
90
|
return divIcon({
|
|
95
|
-
html:
|
|
91
|
+
html: pinMarkerHtml(getColors(props.color).base, props.label),
|
|
96
92
|
iconSize: [size, size],
|
|
97
93
|
className: props.selected ? 'fs-map-marker fs-map-pin fs-map-pin-selected' : 'fs-map-marker fs-map-pin',
|
|
98
94
|
iconAnchor: [size / 2, size / 2],
|
|
@@ -106,11 +102,11 @@ export default {
|
|
|
106
102
|
});
|
|
107
103
|
|
|
108
104
|
const onClick = (event: MouseEvent) => {
|
|
109
|
-
if
|
|
105
|
+
if(props.to) {
|
|
110
106
|
handleRoutingEvent(event, props.to, true);
|
|
111
107
|
return;
|
|
112
108
|
}
|
|
113
|
-
|
|
109
|
+
|
|
114
110
|
emit('click', {
|
|
115
111
|
...event,
|
|
116
112
|
latlng: props.latlng
|
|
@@ -118,7 +114,7 @@ export default {
|
|
|
118
114
|
}
|
|
119
115
|
|
|
120
116
|
const onAuxClick = (event: MouseEvent) => {
|
|
121
|
-
if
|
|
117
|
+
if(props.to) {
|
|
122
118
|
handleRoutingEvent(event, props.to);
|
|
123
119
|
return;
|
|
124
120
|
}
|
|
@@ -130,11 +126,11 @@ export default {
|
|
|
130
126
|
}
|
|
131
127
|
|
|
132
128
|
watch(map, () => {
|
|
133
|
-
if
|
|
129
|
+
if(!map.value) {
|
|
134
130
|
return;
|
|
135
131
|
}
|
|
136
132
|
|
|
137
|
-
if
|
|
133
|
+
if(markerClusterGroup && markerClusterGroup.value) {
|
|
138
134
|
actualMarker.value.addTo(markerClusterGroup.value);
|
|
139
135
|
} else {
|
|
140
136
|
actualMarker.value.addTo(map.value);
|
|
@@ -142,7 +138,7 @@ export default {
|
|
|
142
138
|
}, { immediate: true });
|
|
143
139
|
|
|
144
140
|
watch([() => props.variant, () => props.color, () => props.selected], () => {
|
|
145
|
-
if
|
|
141
|
+
if(!actualMarker.value || !map.value) {
|
|
146
142
|
return;
|
|
147
143
|
}
|
|
148
144
|
|
|
@@ -151,7 +147,7 @@ export default {
|
|
|
151
147
|
});
|
|
152
148
|
|
|
153
149
|
watch([() => props.latlng?.lat, () => props.latlng?.lng], () => {
|
|
154
|
-
if
|
|
150
|
+
if(!actualMarker.value || !map.value || !props.latlng) {
|
|
155
151
|
return;
|
|
156
152
|
}
|
|
157
153
|
|
|
@@ -159,7 +155,7 @@ export default {
|
|
|
159
155
|
});
|
|
160
156
|
|
|
161
157
|
watch(markerElement, (newMarkerElement) => {
|
|
162
|
-
if
|
|
158
|
+
if(!newMarkerElement) {
|
|
163
159
|
return;
|
|
164
160
|
}
|
|
165
161
|
|
|
@@ -168,8 +164,8 @@ export default {
|
|
|
168
164
|
}, { immediate: true });
|
|
169
165
|
|
|
170
166
|
onUnmounted(() => {
|
|
171
|
-
if
|
|
172
|
-
if
|
|
167
|
+
if(actualMarker.value && map.value) {
|
|
168
|
+
if(markerClusterGroup && markerClusterGroup.value) {
|
|
173
169
|
markerClusterGroup.value.removeLayer(actualMarker.value as Marker);
|
|
174
170
|
} else {
|
|
175
171
|
map.value.removeLayer(actualMarker.value as Marker);
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FSTile
|
|
3
|
+
:activeColor="ColorEnum.Primary"
|
|
4
|
+
:modelValue="$props.modelValue"
|
|
5
|
+
:width="$props.width"
|
|
6
|
+
:height="$props.height"
|
|
7
|
+
padding="16px 24px"
|
|
8
|
+
v-bind="$attrs"
|
|
9
|
+
>
|
|
10
|
+
<FSRow
|
|
11
|
+
:wrap="false"
|
|
12
|
+
>
|
|
13
|
+
<FSCol
|
|
14
|
+
gap="16px"
|
|
15
|
+
width="fill"
|
|
16
|
+
>
|
|
17
|
+
<FSText
|
|
18
|
+
font="text-button"
|
|
19
|
+
>
|
|
20
|
+
{{ $props.label }}
|
|
21
|
+
</FSText>
|
|
22
|
+
<FSRow
|
|
23
|
+
:wrap="false"
|
|
24
|
+
align="center-left"
|
|
25
|
+
>
|
|
26
|
+
<FSIcon>
|
|
27
|
+
mdi-view-dashboard-outline
|
|
28
|
+
</FSIcon>
|
|
29
|
+
<FSText
|
|
30
|
+
font="text-overline"
|
|
31
|
+
>
|
|
32
|
+
{{ $tr('ui.dashboards.dynamic', '{0} dashboard(s)', $props.dashboardsCount) }}
|
|
33
|
+
</FSText>
|
|
34
|
+
</FSRow>
|
|
35
|
+
<FSRow
|
|
36
|
+
:wrap="false"
|
|
37
|
+
align="center-left"
|
|
38
|
+
>
|
|
39
|
+
<FSIconCheck
|
|
40
|
+
variant="fill"
|
|
41
|
+
:value="automaticTransition"
|
|
42
|
+
/>
|
|
43
|
+
<FSText
|
|
44
|
+
font="text-overline"
|
|
45
|
+
>
|
|
46
|
+
{{ automaticTransition
|
|
47
|
+
? $tr('ui.playlist.transition-delay.dynamic', 'Transition : {0}', getTimeBestString($props.delay ?? 0))
|
|
48
|
+
: $tr('ui.playlist.automatic-transition', 'Automatic transition')
|
|
49
|
+
}}
|
|
50
|
+
</FSText>
|
|
51
|
+
</FSRow>
|
|
52
|
+
<FSRow
|
|
53
|
+
:wrap="false"
|
|
54
|
+
align="center-left"
|
|
55
|
+
>
|
|
56
|
+
<FSIconCheck
|
|
57
|
+
variant="fill"
|
|
58
|
+
:value="$props.looped"
|
|
59
|
+
/>
|
|
60
|
+
<FSText
|
|
61
|
+
font="text-overline"
|
|
62
|
+
>
|
|
63
|
+
{{ $tr('entity.playlist.looped', 'Looped') }}
|
|
64
|
+
</FSText>
|
|
65
|
+
</FSRow>
|
|
66
|
+
</FSCol>
|
|
67
|
+
<slot
|
|
68
|
+
name="actions"
|
|
69
|
+
/>
|
|
70
|
+
</FSRow>
|
|
71
|
+
</FSTile>
|
|
72
|
+
</template>
|
|
73
|
+
|
|
74
|
+
<script lang="ts">
|
|
75
|
+
import { computed, defineComponent, type PropType } from "vue";
|
|
76
|
+
|
|
77
|
+
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
78
|
+
|
|
79
|
+
import { getTimeBestString } from "@dative-gpi/foundation-shared-components/utils";
|
|
80
|
+
|
|
81
|
+
import FSIconCheck from "../FSIconCheck.vue";
|
|
82
|
+
import FSTile from "../tiles/FSTile.vue";
|
|
83
|
+
import FSIcon from "../FSIcon.vue";
|
|
84
|
+
import FSText from "../FSText.vue";
|
|
85
|
+
import FSRow from "../FSRow.vue";
|
|
86
|
+
import FSCol from "../FSCol.vue";
|
|
87
|
+
|
|
88
|
+
export default defineComponent({
|
|
89
|
+
name: "FSPlaylistTileUI",
|
|
90
|
+
components: {
|
|
91
|
+
FSIconCheck,
|
|
92
|
+
FSIcon,
|
|
93
|
+
FSTile,
|
|
94
|
+
FSText,
|
|
95
|
+
FSRow,
|
|
96
|
+
FSCol
|
|
97
|
+
},
|
|
98
|
+
inheritAttrs: false,
|
|
99
|
+
props: {
|
|
100
|
+
width: {
|
|
101
|
+
type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
|
|
102
|
+
required: false,
|
|
103
|
+
default: () => [352, 336]
|
|
104
|
+
},
|
|
105
|
+
height: {
|
|
106
|
+
type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
|
|
107
|
+
required: false,
|
|
108
|
+
default: () => 'hug'
|
|
109
|
+
},
|
|
110
|
+
label: {
|
|
111
|
+
type: String as PropType<string>,
|
|
112
|
+
required: true
|
|
113
|
+
},
|
|
114
|
+
dashboardsCount: {
|
|
115
|
+
type: Number,
|
|
116
|
+
required: true
|
|
117
|
+
},
|
|
118
|
+
delay: {
|
|
119
|
+
type: Number ,
|
|
120
|
+
required: false
|
|
121
|
+
},
|
|
122
|
+
looped: {
|
|
123
|
+
type: Boolean,
|
|
124
|
+
required: true
|
|
125
|
+
},
|
|
126
|
+
modelValue: {
|
|
127
|
+
type: Boolean,
|
|
128
|
+
required: false,
|
|
129
|
+
default: false
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
setup(props) {
|
|
133
|
+
|
|
134
|
+
const automaticTransition = computed((): boolean => {
|
|
135
|
+
return props.delay ? props.delay > 0 : false;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
getTimeBestString,
|
|
140
|
+
automaticTransition,
|
|
141
|
+
ColorEnum
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
</script>
|
package/composables/index.ts
CHANGED
|
@@ -5,7 +5,6 @@ export * from "./useBreakpoints";
|
|
|
5
5
|
export * from "./useColors";
|
|
6
6
|
export * from "./useCountUp";
|
|
7
7
|
export * from "./useDebounce";
|
|
8
|
-
export * from "./useDynamicVNode";
|
|
9
8
|
export * from "./useElementVisibility";
|
|
10
9
|
export * from "./useMapLayers";
|
|
11
10
|
export * from "./useRules";
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"url": "https://github.com/Dative-GPI/foundation-shared-ui.git"
|
|
5
5
|
},
|
|
6
6
|
"sideEffects": false,
|
|
7
|
-
"version": "1.0.194-
|
|
7
|
+
"version": "1.0.194-playlists-02",
|
|
8
8
|
"description": "",
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "ISC",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@dative-gpi/foundation-shared-domain": "1.0.194-
|
|
17
|
-
"@dative-gpi/foundation-shared-services": "1.0.194-
|
|
16
|
+
"@dative-gpi/foundation-shared-domain": "1.0.194-playlists-02",
|
|
17
|
+
"@dative-gpi/foundation-shared-services": "1.0.194-playlists-02"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@dative-gpi/bones-ui": "^1.0.0",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"sass": "1.71.1",
|
|
39
39
|
"sass-loader": "13.3.2"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "aadd89bd31e3423781f48a258c89ababbbcb00cb"
|
|
42
42
|
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { uuidv4 } from "@dative-gpi/bones-ui";
|
|
2
|
-
import { h, render, nextTick, getCurrentInstance, onBeforeUnmount, type Component, type VNode } from "vue";
|
|
3
|
-
|
|
4
|
-
export function useDynamicVNode<TProps extends Record<string, any>>(component: Component) {
|
|
5
|
-
const id = uuidv4();
|
|
6
|
-
|
|
7
|
-
let vnode: VNode | null = null;
|
|
8
|
-
let container: HTMLElement | null = null;
|
|
9
|
-
|
|
10
|
-
const instance = getCurrentInstance();
|
|
11
|
-
if (!instance) {
|
|
12
|
-
throw new Error("useDynamicVNode must be used inside setup()");
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const appContext = instance.appContext;
|
|
16
|
-
|
|
17
|
-
const mount = async (props: TProps) => {
|
|
18
|
-
await nextTick();
|
|
19
|
-
|
|
20
|
-
const mountPoint = document.getElementById(id);
|
|
21
|
-
if (!mountPoint) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
unmount();
|
|
26
|
-
|
|
27
|
-
container = mountPoint;
|
|
28
|
-
|
|
29
|
-
vnode = h(component, props);
|
|
30
|
-
vnode.appContext = appContext;
|
|
31
|
-
|
|
32
|
-
render(vnode, container);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const unmount = () => {
|
|
36
|
-
if (container) {
|
|
37
|
-
render(null, container);
|
|
38
|
-
}
|
|
39
|
-
vnode = null;
|
|
40
|
-
container = null;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const sanitizeStyle = (style?: string): string =>
|
|
44
|
-
style
|
|
45
|
-
? style.replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">")
|
|
46
|
-
: "";
|
|
47
|
-
|
|
48
|
-
const getHtml = (style?: string) => {
|
|
49
|
-
const safeStyle = sanitizeStyle(style);
|
|
50
|
-
return `<div id="${id}"${safeStyle ? ` style="${safeStyle}"` : ""}></div>`;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
onBeforeUnmount(unmount);
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
mount,
|
|
57
|
-
unmount,
|
|
58
|
-
getHtml
|
|
59
|
-
};
|
|
60
|
-
}
|