@dative-gpi/foundation-shared-components 0.0.11 → 0.0.13

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 (98) hide show
  1. package/aliases/FSButton.ts +8 -6
  2. package/components/FSBreadcrumbs.vue +3 -1
  3. package/components/FSButton.vue +13 -10
  4. package/components/FSCalendar.vue +4 -3
  5. package/components/FSCalendarTwin.vue +4 -3
  6. package/components/FSCarousel.vue +3 -1
  7. package/components/FSCheckbox.vue +8 -6
  8. package/components/FSChip.vue +5 -3
  9. package/components/FSClock.vue +50 -34
  10. package/components/FSColor.vue +3 -1
  11. package/components/FSColorIcon.vue +3 -1
  12. package/components/FSContainer.vue +4 -2
  13. package/components/FSDivider.vue +49 -8
  14. package/components/FSFadeOut.vue +3 -1
  15. package/components/FSFileButton.vue +4 -3
  16. package/components/FSForm.vue +52 -0
  17. package/components/FSImage.vue +42 -33
  18. package/components/FSLabel.vue +105 -0
  19. package/components/FSLink.vue +95 -0
  20. package/components/FSPagination.vue +96 -0
  21. package/components/FSPermissions.vue +0 -0
  22. package/components/FSRadio.vue +8 -6
  23. package/components/FSRemoveDialog.vue +1 -1
  24. package/components/FSSlideGroup.vue +2 -1
  25. package/components/FSSlider.vue +5 -3
  26. package/components/FSSubmitDialog.vue +2 -2
  27. package/components/FSSwitch.vue +9 -7
  28. package/components/FSTabs.vue +4 -3
  29. package/components/FSTag.vue +4 -2
  30. package/components/FSText.vue +3 -2
  31. package/components/FSWrapGroup.vue +2 -1
  32. package/components/deviceOrganisations/FSConnectivity.vue +2 -1
  33. package/components/deviceOrganisations/FSWorstAlert.vue +2 -1
  34. package/components/{FSAutocompleteField.vue → fields/FSAutocompleteField.vue} +25 -22
  35. package/components/fields/FSColorField.vue +194 -0
  36. package/components/{FSDateField.vue → fields/FSDateField.vue} +18 -52
  37. package/components/{FSDateRangeField.vue → fields/FSDateRangeField.vue} +22 -67
  38. package/components/{FSDateTimeField.vue → fields/FSDateTimeField.vue} +20 -54
  39. package/components/{FSDateTimeRangeField.vue → fields/FSDateTimeRangeField.vue} +27 -70
  40. package/components/{FSIconField.vue → fields/FSIconField.vue} +20 -53
  41. package/components/{FSNumberField.vue → fields/FSNumberField.vue} +0 -24
  42. package/components/{FSPasswordField.vue → fields/FSPasswordField.vue} +9 -31
  43. package/components/{FSRichTextField.vue → fields/FSRichTextField.vue} +10 -9
  44. package/components/{FSSearchField.vue → fields/FSSearchField.vue} +47 -14
  45. package/components/{FSSelectField.vue → fields/FSSelectField.vue} +22 -24
  46. package/components/{FSTagField.vue → fields/FSTagField.vue} +19 -53
  47. package/components/{FSTextArea.vue → fields/FSTextArea.vue} +28 -27
  48. package/components/{FSTextField.vue → fields/FSTextField.vue} +23 -21
  49. package/components/fields/FSTimeField.vue +104 -0
  50. package/components/fields/FSTimeSlotField.vue +263 -0
  51. package/components/lists/FSDataTableUI.vue +7 -6
  52. package/components/lists/FSFilterButton.vue +25 -17
  53. package/components/lists/FSHiddenButton.vue +1 -0
  54. package/components/lists/FSLoadDataTable.vue +88 -0
  55. package/components/tiles/FSDeviceOrganisationTileUI.vue +5 -10
  56. package/components/tiles/FSGroupTileUI.vue +5 -10
  57. package/components/{FSLoadTile.vue → tiles/FSLoadTile.vue} +9 -7
  58. package/components/{FSTile.vue → tiles/FSTile.vue} +5 -4
  59. package/composables/index.ts +2 -0
  60. package/composables/useBreakpoints.ts +7 -5
  61. package/composables/useDebounce.ts +22 -0
  62. package/composables/useRules.ts +72 -0
  63. package/elements/FSFormElement.ts +17 -0
  64. package/icons/flags/France.vue +9 -0
  65. package/icons/flags/Germany.vue +7 -0
  66. package/icons/flags/GreatBritain.vue +9 -0
  67. package/icons/flags/Italy.vue +9 -0
  68. package/icons/flags/Portugal.vue +59 -0
  69. package/icons/flags/Spain.vue +546 -0
  70. package/icons/flags/UnitedStates.vue +12 -0
  71. package/icons/sets.ts +17 -0
  72. package/models/rules.ts +10 -1
  73. package/package.json +6 -4
  74. package/pages/FSExternalIdentityButton.vue +64 -0
  75. package/pages/FSLanguageSetter.vue +140 -0
  76. package/pages/FSLoginPage.vue +253 -0
  77. package/styles/components/fs_clock.scss +4 -0
  78. package/styles/components/fs_color_field.scss +17 -0
  79. package/styles/components/fs_divider.scss +5 -0
  80. package/styles/components/fs_image.scss +12 -1
  81. package/styles/components/fs_label.scss +86 -0
  82. package/styles/components/fs_link.scss +6 -0
  83. package/styles/components/fs_load_data_table.scss +77 -0
  84. package/styles/components/fs_pagination.scss +11 -0
  85. package/styles/components/fs_time_field.scss +3 -0
  86. package/styles/components/fs_timeslot_field.scss +75 -0
  87. package/styles/components/index.scss +7 -0
  88. package/styles/globals/text_fonts.scss +18 -0
  89. package/styles/main.scss +3 -1
  90. package/styles/pages/fs_language_setter.scss +55 -0
  91. package/styles/pages/index.scss +1 -0
  92. package/utils/color.ts +7 -0
  93. package/utils/css.ts +2 -1
  94. package/utils/index.ts +3 -1
  95. package/utils/time.ts +29 -0
  96. package/components/FSHeaderButton.vue +0 -17
  97. package/components/lists/FSDataIteratorGroup.vue +0 -7
  98. package/index.ts +0 -6
@@ -0,0 +1,12 @@
1
+ <template>
2
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-us" viewBox="0 0 640 480">
3
+ <g fill-rule="evenodd">
4
+ <g stroke-width="1pt">
5
+ <path fill="#bd3d44" d="M0 0h972.8v39.4H0zm0 78.8h972.8v39.4H0zm0 78.7h972.8V197H0zm0 78.8h972.8v39.4H0zm0 78.8h972.8v39.4H0zm0 78.7h972.8v39.4H0zm0 78.8h972.8V512H0z" transform="scale(.9375)"/>
6
+ <path fill="#fff" d="M0 39.4h972.8v39.4H0zm0 78.8h972.8v39.3H0zm0 78.7h972.8v39.4H0zm0 78.8h972.8v39.4H0zm0 78.8h972.8v39.4H0zm0 78.7h972.8v39.4H0z" transform="scale(.9375)"/>
7
+ </g>
8
+ <path fill="#192f5d" d="M0 0h389.1v275.7H0z" transform="scale(.9375)"/>
9
+ <path fill="#fff" d="M32.4 11.8 36 22.7h11.4l-9.2 6.7 3.5 11-9.3-6.8-9.2 6.7 3.5-10.9-9.3-6.7H29zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.5 11-9.2-6.8-9.3 6.7 3.5-10.9-9.2-6.7h11.4zm64.8 0 3.6 10.9H177l-9.2 6.7 3.5 11-9.3-6.8-9.2 6.7 3.5-10.9-9.3-6.7h11.5zm64.9 0 3.5 10.9H242l-9.3 6.7 3.6 11-9.3-6.8-9.3 6.7 3.6-10.9-9.3-6.7h11.4zm64.8 0 3.6 10.9h11.4l-9.2 6.7 3.5 11-9.3-6.8-9.2 6.7 3.5-10.9-9.2-6.7h11.4zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.6 11-9.3-6.8-9.3 6.7 3.6-10.9-9.3-6.7h11.5zM64.9 39.4l3.5 10.9h11.5L70.6 57 74 67.9l-9-6.7-9.3 6.7L59 57l-9-6.7h11.4zm64.8 0 3.6 10.9h11.4l-9.3 6.7 3.6 10.9-9.3-6.7-9.3 6.7L124 57l-9.3-6.7h11.5zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.5 10.9-9.2-6.7-9.3 6.7 3.5-10.9-9.2-6.7H191zm64.8 0 3.6 10.9h11.4l-9.3 6.7 3.6 10.9-9.3-6.7-9.2 6.7 3.5-10.9-9.3-6.7H256zm64.9 0 3.5 10.9h11.5L330 57l3.5 10.9-9.2-6.7-9.3 6.7 3.5-10.9-9.2-6.7h11.4zM32.4 66.9 36 78h11.4l-9.2 6.7 3.5 10.9-9.3-6.8-9.2 6.8 3.5-11-9.3-6.7H29zm64.9 0 3.5 11h11.5l-9.3 6.7 3.5 10.9-9.2-6.8-9.3 6.8 3.5-11-9.2-6.7h11.4zm64.8 0 3.6 11H177l-9.2 6.7 3.5 10.9-9.3-6.8-9.2 6.8 3.5-11-9.3-6.7h11.5zm64.9 0 3.5 11H242l-9.3 6.7 3.6 10.9-9.3-6.8-9.3 6.8 3.6-11-9.3-6.7h11.4zm64.8 0 3.6 11h11.4l-9.2 6.7 3.5 10.9-9.3-6.8-9.2 6.8 3.5-11-9.2-6.7h11.4zm64.9 0 3.5 11h11.5l-9.3 6.7 3.6 10.9-9.3-6.8-9.3 6.8 3.6-11-9.3-6.7h11.5zM64.9 94.5l3.5 10.9h11.5l-9.3 6.7 3.5 11-9.2-6.8-9.3 6.7 3.5-10.9-9.2-6.7h11.4zm64.8 0 3.6 10.9h11.4l-9.3 6.7 3.6 11-9.3-6.8-9.3 6.7 3.6-10.9-9.3-6.7h11.5zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.5 11-9.2-6.8-9.3 6.7 3.5-10.9-9.2-6.7H191zm64.8 0 3.6 10.9h11.4l-9.2 6.7 3.5 11-9.3-6.8-9.2 6.7 3.5-10.9-9.3-6.7H256zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.5 11-9.2-6.8-9.3 6.7 3.5-10.9-9.2-6.7h11.4zM32.4 122.1 36 133h11.4l-9.2 6.7 3.5 11-9.3-6.8-9.2 6.7 3.5-10.9-9.3-6.7H29zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.5 10.9-9.2-6.7-9.3 6.7 3.5-10.9-9.2-6.7h11.4zm64.8 0 3.6 10.9H177l-9.2 6.7 3.5 11-9.3-6.8-9.2 6.7 3.5-10.9-9.3-6.7h11.5zm64.9 0 3.5 10.9H242l-9.3 6.7 3.6 11-9.3-6.8-9.3 6.7 3.6-10.9-9.3-6.7h11.4zm64.8 0 3.6 10.9h11.4l-9.2 6.7 3.5 11-9.3-6.8-9.2 6.7 3.5-10.9-9.2-6.7h11.4zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.6 11-9.3-6.8-9.3 6.7 3.6-10.9-9.3-6.7h11.5zM64.9 149.7l3.5 10.9h11.5l-9.3 6.7 3.5 10.9-9.2-6.8-9.3 6.8 3.5-11-9.2-6.7h11.4zm64.8 0 3.6 10.9h11.4l-9.3 6.7 3.6 10.9-9.3-6.8-9.3 6.8 3.6-11-9.3-6.7h11.5zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.5 10.9-9.2-6.8-9.3 6.8 3.5-11-9.2-6.7H191zm64.8 0 3.6 10.9h11.4l-9.2 6.7 3.5 10.9-9.3-6.8-9.2 6.8 3.5-11-9.3-6.7H256zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.5 10.9-9.2-6.8-9.3 6.8 3.5-11-9.2-6.7h11.4zM32.4 177.2l3.6 11h11.4l-9.2 6.7 3.5 10.8-9.3-6.7-9.2 6.7 3.5-10.9-9.3-6.7H29zm64.9 0 3.5 11h11.5l-9.3 6.7 3.6 10.8-9.3-6.7-9.3 6.7 3.6-10.9-9.3-6.7h11.4zm64.8 0 3.6 11H177l-9.2 6.7 3.5 10.8-9.3-6.7-9.2 6.7 3.5-10.9-9.3-6.7h11.5zm64.9 0 3.5 11H242l-9.3 6.7 3.6 10.8-9.3-6.7-9.3 6.7 3.6-10.9-9.3-6.7h11.4zm64.8 0 3.6 11h11.4l-9.2 6.7 3.5 10.8-9.3-6.7-9.2 6.7 3.5-10.9-9.2-6.7h11.4zm64.9 0 3.5 11h11.5l-9.3 6.7 3.6 10.8-9.3-6.7-9.3 6.7 3.6-10.9-9.3-6.7h11.5zM64.9 204.8l3.5 10.9h11.5l-9.3 6.7 3.5 11-9.2-6.8-9.3 6.7 3.5-10.9-9.2-6.7h11.4zm64.8 0 3.6 10.9h11.4l-9.3 6.7 3.6 11-9.3-6.8-9.3 6.7 3.6-10.9-9.3-6.7h11.5zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.5 11-9.2-6.8-9.3 6.7 3.5-10.9-9.2-6.7H191zm64.8 0 3.6 10.9h11.4l-9.2 6.7 3.5 11-9.3-6.8-9.2 6.7 3.5-10.9-9.3-6.7H256zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.5 11-9.2-6.8-9.3 6.7 3.5-10.9-9.2-6.7h11.4zM32.4 232.4l3.6 10.9h11.4l-9.2 6.7 3.5 10.9-9.3-6.7-9.2 6.7 3.5-11-9.3-6.7H29zm64.9 0 3.5 10.9h11.5L103 250l3.6 10.9-9.3-6.7-9.3 6.7 3.6-11-9.3-6.7h11.4zm64.8 0 3.6 10.9H177l-9 6.7 3.5 10.9-9.3-6.7-9.2 6.7 3.5-11-9.3-6.7h11.5zm64.9 0 3.5 10.9H242l-9.3 6.7 3.6 10.9-9.3-6.7-9.3 6.7 3.6-11-9.3-6.7h11.4zm64.8 0 3.6 10.9h11.4l-9.2 6.7 3.5 10.9-9.3-6.7-9.2 6.7 3.5-11-9.2-6.7h11.4zm64.9 0 3.5 10.9h11.5l-9.3 6.7 3.6 10.9-9.3-6.7-9.3 6.7 3.6-11-9.3-6.7h11.5z" transform="scale(.9375)"/>
10
+ </g>
11
+ </svg>
12
+ </template>
package/icons/sets.ts ADDED
@@ -0,0 +1,17 @@
1
+ import France from "./flags/France.vue";
2
+ import Germany from "./flags/Germany.vue";
3
+ import GreatBritain from "./flags/GreatBritain.vue";
4
+ import Italy from "./flags/Italy.vue";
5
+ import Portugal from "./flags/Portugal.vue";
6
+ import Spain from "./flags/Spain.vue";
7
+ import UnitedStates from "./flags/UnitedStates.vue";
8
+
9
+ export const Flags = {
10
+ france: France,
11
+ germany: Germany,
12
+ greatBritain: GreatBritain,
13
+ italy: Italy,
14
+ portugal: Portugal,
15
+ spain: Spain,
16
+ unitedStates: UnitedStates
17
+ };
package/models/rules.ts CHANGED
@@ -1,4 +1,7 @@
1
- import { useTimeZone, useTranslationsProvider } from "@dative-gpi/foundation-shared-services/composables";
1
+ import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
2
+ import { useTimeZone } from "@dative-gpi/foundation-shared-services/composables";
3
+
4
+ import { getTimeBestString } from "../utils";
2
5
 
3
6
  const { epochToLongDateFormat } = useTimeZone()!;
4
7
  const { $tr } = useTranslationsProvider();
@@ -47,4 +50,10 @@ export const AutocompleteRules = {
47
50
  required: (message: string) => (value: string) => !!value || (message ?? $tr("ui.rules.required", "Required")),
48
51
  min: (min: number, message: string) => (value: string[]) => (Array.isArray(value) && value.length >= min) || (message ?? $tr("ui.rules.autocomplete-min", "Must select at least {0} elements", min.toString())),
49
52
  max: (max: number, message: string) => (value: string[]) => (Array.isArray(value) && value.length <= max) || (message ?? $tr("ui.rules.autocomplete-max", "Must select at most {0} elements", max.toString()))
53
+ };
54
+
55
+ export const TimeRules = {
56
+ required: (message: string) => (value: number) => !!value || (message ?? $tr("ui.rules.required", "Required")),
57
+ min: (min: number, message: string) => (value: number) => value >= min || (message ?? $tr("ui.rules.time-min", "Must be more than {0}", getTimeBestString(min))),
58
+ max: (max: number, message: string) => (value: number) => value <= max || (message ?? $tr("ui.rules.time-max", "Must be less than {0}", getTimeBestString(max)))
50
59
  };
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@dative-gpi/foundation-shared-components",
3
- "version": "0.0.11",
3
+ "sideEffects": false,
4
+ "version": "0.0.13",
4
5
  "description": "",
5
6
  "publishConfig": {
6
7
  "access": "public"
@@ -9,9 +10,10 @@
9
10
  "author": "",
10
11
  "license": "ISC",
11
12
  "dependencies": {
12
- "@dative-gpi/foundation-shared-domain": "0.0.11",
13
- "@dative-gpi/foundation-shared-services": "0.0.11",
13
+ "@dative-gpi/foundation-shared-domain": "0.0.13",
14
+ "@dative-gpi/foundation-shared-services": "0.0.13",
14
15
  "@fontsource/montserrat": "^5.0.16",
16
+ "@lexical/clipboard": "^0.12.5",
15
17
  "@lexical/history": "^0.12.5",
16
18
  "@lexical/link": "^0.12.5",
17
19
  "@lexical/plain-text": "^0.12.5",
@@ -30,5 +32,5 @@
30
32
  "sass": "^1.69.5",
31
33
  "sass-loader": "^13.3.2"
32
34
  },
33
- "gitHead": "4f28939e7d42ab1ef8319c614fbc210b1291fd79"
35
+ "gitHead": "c99a5f4be0427449b3b00ef6d467528bae8b1ada"
34
36
  }
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <FSButton
3
+ style="flex: 1"
4
+ :href="loginUrl"
5
+ :prependIcon="icon"
6
+ />
7
+ </template>
8
+
9
+ <script lang="ts">
10
+ import { computed, defineComponent, PropType } from "vue";
11
+
12
+ import { LOGIN_EXTERNAL_URL, SIGNUP_EXTERNAL_URL } from "@dative-gpi/foundation-shared-services/config";
13
+ import { buildURL } from "@dative-gpi/bones-ui";
14
+
15
+ import FSButton from "../components/FSButton.vue";
16
+ import FSIcon from "../components/FSIcon.vue";
17
+
18
+ export default defineComponent({
19
+ name: "FSExternalIdentityButton",
20
+ components: {
21
+ FSButton,
22
+ FSIcon
23
+ },
24
+ props: {
25
+ scheme: {
26
+ type: String as PropType<"OpenIdConnect" | "Google" | "Facebook">,
27
+ required: false,
28
+ default: null
29
+ },
30
+ invitation: {
31
+ type: Boolean,
32
+ required: false,
33
+ default: false
34
+ },
35
+ token: {
36
+ type: String,
37
+ required: false,
38
+ default: null
39
+ }
40
+ },
41
+ setup(props) {
42
+ const loginUrl = computed((): string => {
43
+ if (props.invitation) {
44
+ return buildURL(SIGNUP_EXTERNAL_URL(), { scheme: props.scheme, token: props.token });
45
+ }
46
+ return buildURL(LOGIN_EXTERNAL_URL(), { scheme: props.scheme });
47
+ });
48
+
49
+ const icon = computed((): string => {
50
+ switch (props.scheme) {
51
+ case "OpenIdConnect": return "mdi-microsoft";
52
+ case "Google": return "mdi-google";
53
+ case "Facebook": return "mdi-facebook";
54
+ default: return "mdi-login";
55
+ }
56
+ });
57
+
58
+ return {
59
+ loginUrl,
60
+ icon
61
+ };
62
+ }
63
+ })
64
+ </script>
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <v-skeleton-loader
3
+ v-if="fetching"
4
+ type="image"
5
+ :class="loadClasses"
6
+ />
7
+ <FSSelectField
8
+ v-else
9
+ itemValue="code"
10
+ :class="classes"
11
+ :items="entities"
12
+ :modelValue="languageCode"
13
+ :hideHeader="$props.hideHeader"
14
+ @update:modelValue="setLanguageCode($event)"
15
+ v-bind="$attrs"
16
+ >
17
+ <template #selection>
18
+ <FSRow
19
+ align="center-center"
20
+ >
21
+ <FSIcon size="l">
22
+ {{ languageIcon }}
23
+ </FSIcon>
24
+ <FSSpan
25
+ v-if="$props.withLabel"
26
+ >
27
+ {{ languageLabel }}
28
+ </FSSpan>
29
+ </FSRow>
30
+ </template>
31
+ <template #item="{ item, props }">
32
+ <v-list-item v-bind="{ ...props, title: '' }">
33
+ <FSRow
34
+ align="center-left"
35
+ width="hug"
36
+ >
37
+ <FSIcon size="l">
38
+ {{ item.raw.icon }}
39
+ </FSIcon>
40
+ <FSSpan
41
+ v-if="$props.withLabel"
42
+ >
43
+ {{ item.raw.label }}
44
+ </FSSpan>
45
+ </FSRow>
46
+ </v-list-item>
47
+ </template>
48
+ </FSSelectField>
49
+ </template>
50
+
51
+ <script lang="ts">
52
+ import { computed, defineComponent, onMounted } from "vue";
53
+
54
+ import { useLanguageCode } from "@dative-gpi/foundation-shared-services/composables";
55
+ import { useLanguages } from "@dative-gpi/foundation-core-services/composables";
56
+
57
+ import FSSelectField from "../components/fields/FSSelectField.vue";
58
+ import FSIcon from "../components/FSIcon.vue";
59
+ import FSSpan from "../components/FSSpan.vue";
60
+ import FSRow from "../components/FSRow.vue";
61
+
62
+ export default defineComponent({
63
+ name: "FSLanguageSet",
64
+ components: {
65
+ FSSelectField,
66
+ FSIcon,
67
+ FSSpan,
68
+ FSRow
69
+ },
70
+ props: {
71
+ withLabel: {
72
+ type: Boolean,
73
+ required: false,
74
+ default: false
75
+ },
76
+ modelValue: {
77
+ type: String,
78
+ required: false,
79
+ default: null
80
+ },
81
+ hideHeader: {
82
+ type: Boolean,
83
+ required: false,
84
+ default: true
85
+ }
86
+ },
87
+ emits: ["update:modelValue"],
88
+ setup(props) {
89
+ const { getMany, fetching, entities } = useLanguages();
90
+ const { setLanguageCode, languageCode } = useLanguageCode();
91
+
92
+ onMounted(() => {
93
+ getMany();
94
+ });
95
+
96
+ const classes = computed((): string[] => {
97
+ const innerClasses = ["fs-language-setter"];
98
+ if (!props.withLabel) {
99
+ innerClasses.push("fs-language-setter-icon");
100
+ }
101
+ return innerClasses;
102
+ });
103
+
104
+ const loadClasses = computed((): string[] => {
105
+ const innerClasses = ["fs-load-language-setter"];
106
+ if (!props.withLabel) {
107
+ innerClasses.push("fs-load-language-setter-icon");
108
+ }
109
+ return innerClasses;
110
+ });
111
+
112
+ const languageIcon = computed((): string => {
113
+ const language = entities.value.find((entity) => entity.code === languageCode.value);
114
+ if (language) {
115
+ return language.icon;
116
+ }
117
+ return "";
118
+ });
119
+
120
+ const languageLabel = computed((): string => {
121
+ const language = entities.value.find((entity) => entity.code === languageCode.value);
122
+ if (language) {
123
+ return language.label;
124
+ }
125
+ return "";
126
+ });
127
+
128
+ return {
129
+ classes,
130
+ fetching,
131
+ entities,
132
+ loadClasses,
133
+ languageCode,
134
+ languageIcon,
135
+ languageLabel,
136
+ setLanguageCode
137
+ };
138
+ }
139
+ });
140
+ </script>
@@ -0,0 +1,253 @@
1
+ <template>
2
+ <FSRow
3
+ width="100vw"
4
+ gap="0px"
5
+ >
6
+ <FSCol
7
+ align="top-center"
8
+ :width="formWidth"
9
+ >
10
+ <FSCol
11
+ width="min(464px, 100%)"
12
+ padding="56px 0 0 0"
13
+ align="top-center"
14
+ gap="32px"
15
+ >
16
+ <FSCol
17
+ align="top-center"
18
+ gap="24px"
19
+ >
20
+ <FSImage
21
+ borderRadius="0px"
22
+ :imageId="landingPage?.bannerImageId"
23
+ :height="bannerSize.height"
24
+ :width="bannerSize.width"
25
+ />
26
+ <FSPagination
27
+ class="fs-login-page-pagination"
28
+ width="calc(100% - 64px)"
29
+ :modelValue="0"
30
+ :pages="3"
31
+ />
32
+ <FSCol
33
+ gap="24px"
34
+ >
35
+ <FSCol
36
+ gap="12px"
37
+ >
38
+ <FSLanguageSetter />
39
+ <FSCol
40
+ gap="4px"
41
+ >
42
+ <FSLabel
43
+ font="text-h1"
44
+ :label="landingPage?.title"
45
+ />
46
+ <FSLabel
47
+ :label="landingPage?.subTitle"
48
+ />
49
+ </FSCol>
50
+ </FSCol>
51
+ <FSCol
52
+ v-if="securitySettings?.useLocalAccounts"
53
+ gap="16px"
54
+ >
55
+ <FSTextField
56
+ :label="$tr('ui.login-page.email', 'Email')"
57
+ :required="true"
58
+ v-model="innerEmail"
59
+ />
60
+ <FSPasswordField
61
+ :label="$tr('ui.login-page.password', 'Password')"
62
+ :required="true"
63
+ v-model="innerPassword"
64
+ />
65
+ <FSRow
66
+ align="center-left"
67
+ >
68
+ <FSCheckbox
69
+ :label="$tr('ui.login-page.remember-me', 'Remember me')"
70
+ v-model="innerRememberMe"
71
+ />
72
+ <v-spacer />
73
+ <FSLink
74
+ to="https://www.google.com"
75
+ >
76
+ {{ $tr("ui.login-page.forgot-password", "Forgot password?") }}
77
+ </FSLink>
78
+ </FSRow>
79
+ </FSCol>
80
+ <FSButton
81
+ v-if="securitySettings?.useLocalAccounts"
82
+ :label="$tr('ui.login-page.login', 'Login')"
83
+ :color="ColorEnum.Primary"
84
+ :fullWidth="true"
85
+ />
86
+ </FSCol>
87
+ </FSCol>
88
+ <FSDivider
89
+ v-if="securitySettings && showDivider"
90
+ :label="$tr('ui.login-page.or', 'Or')"
91
+ />
92
+ <FSRow
93
+ align="center-center"
94
+ width="fill"
95
+ :wrap="false"
96
+ >
97
+ <FSExternalIdentityButton
98
+ v-if="securitySettings && securitySettings.useGoogle"
99
+ scheme="Google"
100
+ />
101
+ <FSExternalIdentityButton
102
+ v-if="securitySettings && securitySettings.useFacebook"
103
+ scheme="Facebook"
104
+ />
105
+ <FSExternalIdentityButton
106
+ v-if="securitySettings && securitySettings.useMicrosoft"
107
+ scheme="OpenIdConnect"
108
+ />
109
+ </FSRow>
110
+ <FSLink
111
+ v-if="landingPage && landingPage.faqLink"
112
+ :to="landingPage.faqLink"
113
+ >
114
+ {{ $tr("ui.login-page.frequently-asked-questions", "Frequently asked questions") }}
115
+ </FSLink>
116
+ </FSCol>
117
+ </FSCol>
118
+ <FSImage
119
+ borderRadius="0px"
120
+ :imageId="landingPage?.bannerImageId"
121
+ :height="backgroundSize.height"
122
+ :width="backgroundSize.width"
123
+ />
124
+ </FSRow>
125
+ </template>
126
+
127
+ <script lang="ts">
128
+ import { computed, defineComponent, onMounted, ref } from "vue";
129
+
130
+ import { useCurrentLandingPage, useCurrentSecuritySettings } from "@dative-gpi/foundation-shared-services/composables";
131
+ import { useBreakpoints } from "@dative-gpi/foundation-shared-components/composables";
132
+ import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
133
+
134
+ import FSExternalIdentityButton from "./FSExternalIdentityButton.vue";
135
+ import FSLanguageSetter from "./FSLanguageSetter.vue";
136
+
137
+ import FSPasswordField from "../components/fields/FSPasswordField.vue";
138
+ import FSTextField from "../components/fields/FSTextField.vue";
139
+ import FSPagination from "../components/FSPagination.vue";
140
+ import FSCheckbox from "../components/FSCheckbox.vue"
141
+ import FSDivider from "../components/FSDivider.vue";
142
+ import FSImage from "../components/FSImage.vue";
143
+ import FSLabel from "../components/FSLabel.vue";
144
+ import FSLink from "../components/FSLink.vue";
145
+ import FSRow from "../components/FSRow.vue";
146
+ import FSCol from "../components/FSCol.vue";
147
+
148
+ export default defineComponent({
149
+ name: "FSLoginPage",
150
+ components: {
151
+ FSExternalIdentityButton,
152
+ FSLanguageSetter,
153
+ FSPasswordField,
154
+ FSPagination,
155
+ FSTextField,
156
+ FSCheckbox,
157
+ FSDivider,
158
+ FSImage,
159
+ FSLabel,
160
+ FSLink,
161
+ FSRow,
162
+ FSCol
163
+ },
164
+ props: {
165
+ backgroundImageId: {
166
+ type: String,
167
+ required: false,
168
+ default: null
169
+ },
170
+ bannerImageId: {
171
+ type: String,
172
+ required: false,
173
+ default: null
174
+ }
175
+ },
176
+ setup(props) {
177
+ const { getting: gettingLandingPage, get: getLandingPage, entity: landingPage } = useCurrentLandingPage();
178
+ const { get: getSecuritySettings, entity: securitySettings } = useCurrentSecuritySettings();
179
+ const { isExtraSmall, isMobileSized } = useBreakpoints();
180
+
181
+ const innerEmail = ref("");
182
+ const innerPassword = ref("");
183
+ const innerRememberMe = ref(false);
184
+
185
+ const backgroundSize = computed((): { width: number | string, height: number | string } => {
186
+ if (!gettingLandingPage && (!landingPage.value || !landingPage.value.bannerImageId)) {
187
+ return { width: 0, height: 0 };
188
+ }
189
+ if (isExtraSmall.value) {
190
+ return { width: 0, height: 0 };
191
+ }
192
+ if (isMobileSized.value) {
193
+ return { width: "50%", height: "100vh" };
194
+ }
195
+ return { width: "60%", height: "100vh" };
196
+ });
197
+
198
+ const bannerSize = computed((): { width: number | string, height: number | string } => {
199
+ if (!gettingLandingPage && (!landingPage.value || !landingPage.value.bannerImageId)) {
200
+ return { width: 0, height: 0 };
201
+ }
202
+ if (isExtraSmall.value) {
203
+ return { width: 240, height: 45 };
204
+ }
205
+ return { width: 360, height: 60 };
206
+ });
207
+
208
+ const formWidth = computed((): string => {
209
+ if (!gettingLandingPage && (!landingPage.value || !landingPage.value.backgroundImageId)) {
210
+ return "100%";
211
+ }
212
+ if (isExtraSmall.value) {
213
+ return "100%";
214
+ }
215
+ if (isMobileSized.value) {
216
+ return "50%";
217
+ }
218
+ return "40%";
219
+ });
220
+
221
+ const showDivider = computed((): boolean => {
222
+ if (!securitySettings.value) {
223
+ return true;
224
+ }
225
+ if (!securitySettings.value.useLocalAccounts) {
226
+ return false;
227
+ }
228
+ if (!securitySettings.value.useGoogle && !securitySettings.value.useFacebook && !securitySettings.value.useMicrosoft) {
229
+ return false;
230
+ }
231
+ return true;
232
+ });
233
+
234
+ onMounted(() => {
235
+ getSecuritySettings();
236
+ getLandingPage();
237
+ });
238
+
239
+ return {
240
+ ColorEnum,
241
+ securitySettings,
242
+ landingPage,
243
+ innerEmail,
244
+ innerPassword,
245
+ innerRememberMe,
246
+ backgroundSize,
247
+ bannerSize,
248
+ formWidth,
249
+ showDivider
250
+ };
251
+ }
252
+ });
253
+ </script>
@@ -1,3 +1,7 @@
1
+ .fs-clock-date {
2
+ max-width: calc(100% - 198px);
3
+ }
4
+
1
5
  .fs-clock-field {
2
6
  padding: 0px !important;
3
7
  width: 72px !important;
@@ -0,0 +1,17 @@
1
+ .fs-color-field {
2
+ min-width:190px;
3
+ }
4
+
5
+ .fs-color-field-opacity {
6
+ min-width: 150px;
7
+ }
8
+
9
+ .fs-color-field .v-field__prepend-inner > .v-icon {
10
+ opacity: 1 !important;
11
+ }
12
+
13
+ .fs-color-field-picker {
14
+ background: none !important;
15
+ min-width: auto !important;
16
+ width: 100% !important;
17
+ }
@@ -2,4 +2,9 @@
2
2
  width: var(--fs-divider-width);
3
3
  border-bottom: 1.3px solid var(--fs-divider-color);
4
4
  border-radius: 3px;
5
+ }
6
+
7
+ .fs-divider-around {
8
+ border-bottom: 1.3px solid var(--fs-divider-color);
9
+ border-radius: 3px;
5
10
  }
@@ -1,5 +1,16 @@
1
+ .fs-load-image {
2
+ border-radius: var(--fs-image-border-radius);
3
+ max-height: 100%;
4
+ height: 100%;
5
+
6
+ & > .v-skeleton-loader__image {
7
+ max-height: 100%;
8
+ height: 100%;
9
+ }
10
+ }
11
+
1
12
  .fs-image {
2
- border-radius: 4px;
13
+ border-radius: var(--fs-image-border-radius);
3
14
 
4
15
  &.v-responsive {
5
16
  flex: 0 0 auto !important;
@@ -0,0 +1,86 @@
1
+ .fs-label {
2
+ color: var(--fs-label-color);
3
+
4
+ @extend .fs-span;
5
+ }
6
+
7
+ .fs-load-label {
8
+ & > .v-skeleton-loader__text {
9
+ margin: 0px;
10
+ height: 100%;
11
+ }
12
+
13
+ &.text-h1 {
14
+ width: calc(50% - 32px);
15
+
16
+ @include web {
17
+ height: 36px;
18
+ }
19
+
20
+ @include mobile {
21
+ height: 29px;
22
+ }
23
+ }
24
+
25
+ &.text-h2 {
26
+ width: calc(60% - 32px);
27
+
28
+ @include web {
29
+ height: 27px;
30
+ }
31
+
32
+ @include mobile {
33
+ height: 22px;
34
+ }
35
+ }
36
+
37
+ &.text-h3 {
38
+ width: calc(65% - 32px);
39
+
40
+ @include web {
41
+ height: 21px;
42
+ }
43
+
44
+ @include mobile {
45
+ height: 17px;
46
+ }
47
+ }
48
+
49
+ &.text-h4 {
50
+ width: calc(75% - 32px);
51
+
52
+ @include web {
53
+ height: 16px;
54
+ }
55
+
56
+ @include mobile {
57
+ height: 14px;
58
+ }
59
+ }
60
+
61
+ &.text-body,
62
+ &.text-button {
63
+ width: calc(75% - 32px);
64
+
65
+ @include web {
66
+ height: 14px;
67
+ }
68
+
69
+ @include mobile {
70
+ height: 12px;
71
+ }
72
+ }
73
+
74
+ &.text-overline,
75
+ &.text-underline {
76
+ width: calc(75% - 32px);
77
+
78
+ @include web {
79
+ height: 12px;
80
+ }
81
+
82
+ @include mobile {
83
+ height: 10px;
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,6 @@
1
+ .fs-link {
2
+ color: var(--fs-link-color);
3
+ text-decoration: none;
4
+
5
+ @extend .fs-span;
6
+ }