@dative-gpi/foundation-shared-components 1.0.50 → 1.0.52

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.
Files changed (34) hide show
  1. package/components/FSCard.vue +6 -2
  2. package/components/FSClickable.vue +6 -9
  3. package/components/FSDialogRemove.vue +1 -0
  4. package/components/agenda/FSAgenda.vue +210 -0
  5. package/components/agenda/FSAgendaDialogCalendar.vue +76 -0
  6. package/components/agenda/FSAgendaHeader.vue +190 -0
  7. package/components/agenda/FSAgendaHorizontalEvent.vue +162 -0
  8. package/components/agenda/FSAgendaHorizontalTimeLineMarker.vue +46 -0
  9. package/components/agenda/FSAgendaHoursCol.vue +103 -0
  10. package/components/agenda/FSAgendaHoursRow.vue +124 -0
  11. package/components/agenda/FSAgendaVerticalEvent.vue +160 -0
  12. package/components/agenda/FSAgendaVerticalTimeLineMarker.vue +46 -0
  13. package/components/agenda/FSDayAgenda.vue +200 -0
  14. package/components/agenda/FSMonthAgenda.vue +258 -0
  15. package/components/agenda/FSSelectAgendaMode.vue +54 -0
  16. package/components/agenda/FSWeekAgenda.vue +329 -0
  17. package/components/fields/FSCommentField.vue +93 -0
  18. package/components/tiles/FSChartTileUI.vue +116 -0
  19. package/components/tiles/FSCommentTileUI.vue +149 -0
  20. package/components/tiles/FSModelTileUI.vue +59 -0
  21. package/models/agenda.ts +9 -0
  22. package/models/index.ts +1 -0
  23. package/package.json +4 -4
  24. package/styles/components/fs_agenda.scss +32 -0
  25. package/styles/components/fs_agenda_event.scss +41 -0
  26. package/styles/components/fs_agenda_hours_col.scss +4 -0
  27. package/styles/components/fs_agenda_hours_row.scss +13 -0
  28. package/styles/components/fs_agenda_time_line_marker.scss +19 -0
  29. package/styles/components/fs_clickable.scss +4 -2
  30. package/styles/components/fs_dialog.scss +11 -15
  31. package/styles/components/index.scss +5 -0
  32. package/tools/alertsTools.ts +54 -0
  33. package/tools/chartsTools.ts +300 -0
  34. package/tools/index.ts +2 -0
@@ -0,0 +1,200 @@
1
+ <template>
2
+ <FSRow
3
+ class="fs-day-agenda"
4
+ height="100%"
5
+ padding="8px 0 0 0"
6
+ :wrap="false"
7
+ gap="0px"
8
+ :style="style"
9
+ >
10
+ <FSLoader
11
+ v-if="$props.loading"
12
+ width="100%"
13
+ height="100%"
14
+ />
15
+ <FSRow
16
+ v-else
17
+ height="100%"
18
+ gap="0"
19
+ :wrap="false"
20
+ >
21
+ <FSAgendaHoursCol
22
+ :displayNow="$props.nowIsInSelectedRange"
23
+ :modelValue="nowHour"
24
+ />
25
+ <FSCol
26
+ height="100%"
27
+ width="fill"
28
+ class="fs-agenda-body"
29
+ gap="0"
30
+ >
31
+ <span
32
+ v-for="hour in 24"
33
+ class="fs-day-agenda-hour-line"
34
+ :key="hour"
35
+ />
36
+ <FSCol
37
+ style="position: absolute;"
38
+ height="100%"
39
+ padding="0 0 0 3px"
40
+ width="calc(100% - 32px)"
41
+ >
42
+ <slot />
43
+ <FSCol
44
+ style="position: relative;"
45
+ height="100%"
46
+ >
47
+ <FSAgendaVerticalEvent
48
+ v-for="event in dayEvents"
49
+ :key="event.id"
50
+ :variant="event.end < now ? 'past' : event.start > now ? 'future' : 'current'"
51
+ :now="now"
52
+ :dayStart="$props.start"
53
+ :label="event.label"
54
+ :start="event.start"
55
+ :end="event.end"
56
+ :icon="event.icon"
57
+ :iconBis="event.iconBis"
58
+ :id="event.id"
59
+ :color="event.color"
60
+ @click="() => $emit('click:eventId', event.id)"
61
+ >
62
+ <template
63
+ #default="{ label, icon, timeStart, timeEnd, iconBis }"
64
+ >
65
+ <FSCol>
66
+ <FSRow
67
+ class="fs-agenda-event-day-label-container"
68
+ align="center-left"
69
+ gap="4px"
70
+ :wrap="false"
71
+ >
72
+ <FSCol
73
+ height="hug"
74
+ width="fill"
75
+ align="center-left"
76
+ padding="8px 8px 0 8px"
77
+ >
78
+ <FSSpan>
79
+ {{ `${timeStart} - ${timeEnd}` }}
80
+ </FSSpan>
81
+ <FSRow
82
+ align="center-left"
83
+ :wrap="false"
84
+ >
85
+ <FSIcon
86
+ v-if="icon"
87
+ :icon="icon"
88
+ />
89
+ <FSSpan
90
+ font="text-button"
91
+ >
92
+ {{ label }}
93
+ </FSSpan>
94
+ </FSRow>
95
+ </FSCol>
96
+ <FSCol
97
+ v-if="iconBis"
98
+ align="center-right"
99
+ padding="8px 8px 8px 0"
100
+ width="hug"
101
+ >
102
+ <FSIcon
103
+ v-if="iconBis"
104
+ :icon="iconBis"
105
+ />
106
+ </FSCol>
107
+ </FSRow>
108
+ </FSCol>
109
+ </template>
110
+ </FSAgendaVerticalEvent>
111
+ </FSCol>
112
+ </FSCol>
113
+ </FSCol>
114
+ </FSRow>
115
+ </FSRow>
116
+ </template>
117
+
118
+ <script lang="ts">
119
+ import { defineComponent, type PropType, computed, type StyleValue } from 'vue';
120
+
121
+ import { useColors } from "@dative-gpi/foundation-shared-components/composables";
122
+ import { ColorEnum, type FSAgendaEvent } from "@dative-gpi/foundation-shared-components/models";
123
+
124
+ import FSCol from '../FSCol.vue';
125
+ import FSRow from '../FSRow.vue';
126
+ import FSAgendaHoursCol from './FSAgendaHoursCol.vue';
127
+ import FSAgendaVerticalEvent from './FSAgendaVerticalEvent.vue';
128
+ import FSIcon from '../FSIcon.vue';
129
+ import FSSpan from '../FSSpan.vue';
130
+ import FSLoader from '../FSLoader.vue';
131
+
132
+ export default defineComponent({
133
+ name: 'FSDayAgenda',
134
+ components: {
135
+ FSAgendaHoursCol,
136
+ FSAgendaVerticalEvent,
137
+ FSCol,
138
+ FSIcon,
139
+ FSLoader,
140
+ FSRow,
141
+ FSSpan
142
+ },
143
+ props: {
144
+ now: {
145
+ type: Number,
146
+ required: true
147
+ },
148
+ start: {
149
+ type: Number,
150
+ required: true
151
+ },
152
+ end: {
153
+ type: Number,
154
+ required: true
155
+ },
156
+ firstColumnWidth: {
157
+ type: String,
158
+ required: true
159
+ },
160
+ loading: {
161
+ type: Boolean,
162
+ default: false
163
+ },
164
+ events: {
165
+ type: Array as PropType<FSAgendaEvent[]>,
166
+ default: () => []
167
+ },
168
+ nowIsInSelectedRange: {
169
+ type: Boolean,
170
+ required: true
171
+ },
172
+ },
173
+ emits: ['click:eventId'],
174
+ setup(props) {
175
+ const { getColors } = useColors();
176
+
177
+ const lightColors = getColors(ColorEnum.Light);
178
+
179
+ const nowHour = computed(() => new Date(props.now).getHours());
180
+
181
+ const dayEvents = computed(() => {
182
+ return props.events.filter((event) => {
183
+ return (event.start <= props.end && event.start >= props.start) || (event.end <= props.end && event.end >= props.start);
184
+ });
185
+ });
186
+
187
+ const style = computed((): StyleValue => {
188
+ return {
189
+ '--fs-day-agenda-hour-line-color': lightColors.light,
190
+ };
191
+ });
192
+
193
+ return {
194
+ dayEvents,
195
+ nowHour,
196
+ style
197
+ };
198
+ },
199
+ });
200
+ </script>
@@ -0,0 +1,258 @@
1
+ <template>
2
+ <FSCol
3
+ class="fs-agenda-month-container"
4
+ height="100%"
5
+ width="100%"
6
+ gap="0"
7
+ >
8
+ <FSRow
9
+ gap="0"
10
+ :wrap="false"
11
+ >
12
+ <FSCol
13
+ height="100%"
14
+ :width="$props.firstColumnWidth"
15
+ >
16
+ </FSCol>
17
+
18
+ <FSAgendaHoursRow
19
+ :displayNow="$props.nowIsInSelectedRange"
20
+ :modelValue="nowHour"
21
+ />
22
+ </FSRow>
23
+ <FSRow
24
+ class="fs-agenda-month"
25
+ :style="style"
26
+ height="100%"
27
+ :wrap="false"
28
+ gap="0px"
29
+ >
30
+ <FSCol
31
+ class="fs-agenda-label-day-container"
32
+ height="100%"
33
+ gap="0"
34
+ :width="$props.firstColumnWidth"
35
+ >
36
+ <FSCol
37
+ v-for="day in monthDays"
38
+ class="fs-agenda-label-day"
39
+ :style="getDayLabelStyle(day.isNowDay)"
40
+ :key="day.dayNumber"
41
+ height="100%"
42
+ width="100%"
43
+ align="center-center"
44
+ >
45
+ <FSCard
46
+ height="100%"
47
+ width="100%"
48
+ :borderRadius="0"
49
+ :border="false"
50
+ variant="standard"
51
+ :color="day.isNowDay ? 'primary' : 'background'"
52
+ >
53
+ <FSCol
54
+ align="center-center"
55
+ >
56
+ <FSSpan
57
+ :color="day.isNowDay ? 'primary' : 'dark'"
58
+ font="text-overline"
59
+ >
60
+ {{ day.dayNumber }}
61
+ </FSSpan>
62
+ </FSCol>
63
+ </FSCard>
64
+ </FSCol>
65
+ </FSCol>
66
+ <FSCol
67
+ class="fs-agenda-body"
68
+ gap="0"
69
+ height="100%"
70
+ width="100%"
71
+ >
72
+ <slot />
73
+ <template
74
+ v-if="loading"
75
+ >
76
+ <FSLoader
77
+ height="100%"
78
+ width="100%"
79
+ padding="2px"
80
+ />
81
+ </template>
82
+ <template
83
+ v-else
84
+ >
85
+ <FSRow
86
+ v-for="day in monthDays"
87
+ :key="day.dayNumber"
88
+ class="fs-agenda-row-day"
89
+ height="100%"
90
+ width="fill"
91
+ align="center-left"
92
+ >
93
+ <FSAgendaHorizontalEvent
94
+ v-for="event in getDayEvents(day.dayStartEpoch)"
95
+ :key="event.id"
96
+ :now="$props.now"
97
+ :variant="event.end < now ? 'past' : event.start > now ? 'future' : 'current'"
98
+ :dayStart="day.dayStartEpoch"
99
+ :label="event.label"
100
+ :start="event.start"
101
+ :end="event.end"
102
+ :icon="event.icon"
103
+ :id="event.id"
104
+ :color="event.color"
105
+ @click="() => $emit('click:eventId', event.id)"
106
+ >
107
+ <template
108
+ #default="{ label, icon }"
109
+ >
110
+ <FSRow
111
+ align="center-left"
112
+ :wrap="false"
113
+ padding="0 0 0 4px"
114
+ gap="4px"
115
+ >
116
+ <FSIcon
117
+ v-if="icon"
118
+ :icon="icon"
119
+ size="16px"
120
+ />
121
+ <FSSpan
122
+ font="text-overline"
123
+ >
124
+ {{ label }}
125
+ </FSSpan>
126
+ </FSRow>
127
+ </template>
128
+ </FSAgendaHorizontalEvent>
129
+ </FSRow>
130
+ </template>
131
+ </FSCol>
132
+ </FSRow>
133
+ </FSCol>
134
+ </template>
135
+
136
+ <script lang="ts">
137
+ import { defineComponent, computed, type PropType, type StyleValue } from 'vue';
138
+
139
+ import { useColors } from "@dative-gpi/foundation-shared-components/composables";
140
+ import { ColorEnum, type FSAgendaEvent } from "@dative-gpi/foundation-shared-components/models";
141
+
142
+ import FSAgendaHorizontalEvent from './FSAgendaHorizontalEvent.vue';
143
+ import FSAgendaHoursRow from './FSAgendaHoursRow.vue';
144
+ import FSCol from '../FSCol.vue';
145
+ import FSRow from '../FSRow.vue';
146
+ import FSLoader from '../FSLoader.vue';
147
+ import FSIcon from '../FSIcon.vue';
148
+ import FSSpan from '../FSSpan.vue';
149
+ import FSCard from '../FSCard.vue';
150
+
151
+ export default defineComponent({
152
+ name: 'FSMonthAgenda',
153
+ components: {
154
+ FSAgendaHorizontalEvent,
155
+ FSAgendaHoursRow,
156
+ FSCard,
157
+ FSCol,
158
+ FSIcon,
159
+ FSLoader,
160
+ FSRow,
161
+ FSSpan
162
+ },
163
+ props: {
164
+ now: {
165
+ type: Number,
166
+ required: true
167
+ },
168
+ start: {
169
+ type: Number,
170
+ required: true
171
+ },
172
+ end: {
173
+ type: Number,
174
+ required: true
175
+ },
176
+ nowIsInSelectedRange: {
177
+ type: Boolean,
178
+ required: true
179
+ },
180
+ firstColumnWidth: {
181
+ type: String,
182
+ required: true
183
+ },
184
+ loading: {
185
+ type: Boolean,
186
+ default: false
187
+ },
188
+ events: {
189
+ type: Array as PropType<FSAgendaEvent[]>,
190
+ default: () => []
191
+ }
192
+ },
193
+ emits: ['update:start', 'update:end', 'click:eventId'],
194
+ setup(props) {
195
+ const { getColors } = useColors();
196
+
197
+ const primaryColors = getColors(ColorEnum.Primary);
198
+ const lightColors = getColors(ColorEnum.Light);
199
+
200
+ const nowHour = computed(() => new Date(props.now).getHours());
201
+
202
+ const monthDays = computed(() => {
203
+ const monthDaysArray = [];
204
+ const nowDate = new Date(props.now);
205
+
206
+ let currentDay = new Date(props.start);
207
+ const endDate = new Date(props.end);
208
+
209
+ while (currentDay <= endDate) {
210
+ monthDaysArray.push({
211
+ dayNumber: currentDay.getDate(),
212
+ dayStartEpoch: currentDay.getTime(),
213
+ isNowDay: currentDay.toDateString() === nowDate.toDateString(),
214
+ });
215
+
216
+ currentDay.setDate(currentDay.getDate() + 1);
217
+ }
218
+
219
+ return monthDaysArray;
220
+ });
221
+
222
+ const style = computed((): StyleValue => {
223
+ return {
224
+ '--fs-agenda-row-day-border-bottom-color': lightColors.base,
225
+ };
226
+ });
227
+
228
+ const getDayLabelStyle = (isNowDay: boolean = false) => {
229
+ if (isNowDay) {
230
+ return {
231
+ '--fs-agenda-label-day-border-bottom-color': primaryColors.base,
232
+ '--fs-agenda-label-day-border-right-color': lightColors.base,
233
+ };
234
+ }
235
+ return {
236
+ '--fs-agenda-label-day-border-bottom-color': lightColors.base,
237
+ '--fs-agenda-label-day-border-right-color': lightColors.base,
238
+ };
239
+ };
240
+
241
+ const getDayEvents = (dayStartEpoch: number) => {
242
+ return props.events.filter((event) => {
243
+ const isStartingInDay = event.start >= dayStartEpoch && event.start < (dayStartEpoch + 1000 * 60 * 60 * 24);
244
+ const isEndingInDay = event.end >= dayStartEpoch && event.end < (dayStartEpoch + 1000 * 60 * 60 * 24);
245
+ return isStartingInDay || isEndingInDay;
246
+ });
247
+ };
248
+
249
+ return {
250
+ nowHour,
251
+ monthDays,
252
+ style,
253
+ getDayEvents,
254
+ getDayLabelStyle
255
+ };
256
+ },
257
+ });
258
+ </script>
@@ -0,0 +1,54 @@
1
+ <template>
2
+ <FSSelectField
3
+ :items="items"
4
+ :modelValue="$props.modelValue"
5
+ :clearable="false"
6
+ v-bind="$attrs"
7
+ @update:modelValue="$emit('update:modelValue', $event)"
8
+ >
9
+ <template
10
+ #item-prepend="{ item }"
11
+ >
12
+ <FSIcon
13
+ :icon="item.icon"
14
+ />
15
+ </template>
16
+ </FSSelectField>
17
+ </template>
18
+
19
+ <script lang="ts">
20
+ import { defineComponent, type PropType } from 'vue';
21
+
22
+ import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui";
23
+ import { AgendaMode } from '@dative-gpi/foundation-shared-domain/enums/agendas';
24
+
25
+ import FSSelectField from '../fields/FSSelectField.vue';
26
+ import FSIcon from '../FSIcon.vue';
27
+
28
+ export default defineComponent({
29
+ name: 'FSSelectAgendaMode',
30
+ components: {
31
+ FSIcon,
32
+ FSSelectField
33
+ },
34
+ props: {
35
+ modelValue: {
36
+ type: Number as PropType<AgendaMode>,
37
+ default: AgendaMode.Week,
38
+ },
39
+ },
40
+ emits: ['update:modelValue'],
41
+ setup() {
42
+ const { $tr } = useTranslationsProvider();
43
+
44
+ const items = [
45
+ { id: AgendaMode.Week, label: $tr('ui.agenda.week', 'Week'), icon: 'mdi-calendar-week' },
46
+ { id: AgendaMode.Month, label: $tr('ui.agenda.month', 'Month'), icon: 'mdi-calendar-month' },
47
+ ];
48
+
49
+ return {
50
+ items
51
+ };
52
+ }
53
+ });
54
+ </script>