@demos-europe/demosplan-ui 0.0.1

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 (133) hide show
  1. package/LICENSE +21 -0
  2. package/buildTokens.js +59 -0
  3. package/components/DpButton/DpButton.stories.mdx +136 -0
  4. package/components/DpButton/DpButton.vue +118 -0
  5. package/components/DpDetails/DpDetails.stories.mdx +55 -0
  6. package/components/DpDetails/DpDetails.vue +58 -0
  7. package/components/DpIcon/DpIcon.stories.mdx +396 -0
  8. package/components/DpIcon/DpIcon.vue +51 -0
  9. package/components/DpIcon/util/iconVariables.js +148 -0
  10. package/components/DpInput/DpInput.stories.mdx +127 -0
  11. package/components/DpInput/DpInput.vue +284 -0
  12. package/components/DpLabel/DpLabel.stories.mdx +103 -0
  13. package/components/DpLabel/DpLabel.vue +112 -0
  14. package/components/DpLoading/DpLoading.stories.mdx +63 -0
  15. package/components/DpLoading/DpLoading.vue +63 -0
  16. package/components/core/DpAccordion.vue +108 -0
  17. package/components/core/DpAnonymizeText.vue +136 -0
  18. package/components/core/DpAutocomplete.vue +133 -0
  19. package/components/core/DpBulkEditHeader.vue +53 -0
  20. package/components/core/DpButtonIcon.vue +47 -0
  21. package/components/core/DpButtonRow.vue +155 -0
  22. package/components/core/DpCard.vue +54 -0
  23. package/components/core/DpChangeStateAtDate.vue +223 -0
  24. package/components/core/DpCheckboxGroup.vue +93 -0
  25. package/components/core/DpContextualHelp.vue +54 -0
  26. package/components/core/DpCopyPasteButton.vue +47 -0
  27. package/components/core/DpDashboardTaskCard.vue +123 -0
  28. package/components/core/DpDataTable/DataTableSearch.js +44 -0
  29. package/components/core/DpDataTable/DpColumnSelector.vue +133 -0
  30. package/components/core/DpDataTable/DpDataTable.vue +647 -0
  31. package/components/core/DpDataTable/DpDataTableExtended.vue +377 -0
  32. package/components/core/DpDataTable/DpResizeHandle.vue +37 -0
  33. package/components/core/DpDataTable/DpSelectPageItemCount.vue +70 -0
  34. package/components/core/DpDataTable/DpTableHeader.vue +197 -0
  35. package/components/core/DpDataTable/DpTableRow.vue +355 -0
  36. package/components/core/DpDataTable/DpWrapTrigger.vue +48 -0
  37. package/components/core/DpDataTable/lib/ResizableColumns.js +83 -0
  38. package/components/core/DpEditableList.vue +161 -0
  39. package/components/core/DpEditor/DpBoilerPlate.vue +140 -0
  40. package/components/core/DpEditor/DpBoilerPlateModal.vue +166 -0
  41. package/components/core/DpEditor/DpEditor.vue +1281 -0
  42. package/components/core/DpEditor/DpLinkModal.vue +117 -0
  43. package/components/core/DpEditor/DpRecommendationModal/DpInsertableRecommendation.vue +137 -0
  44. package/components/core/DpEditor/DpRecommendationModal.vue +283 -0
  45. package/components/core/DpEditor/DpResizableImage.vue +121 -0
  46. package/components/core/DpEditor/DpUploadModal.vue +121 -0
  47. package/components/core/DpEditor/libs/Decoration.js +66 -0
  48. package/components/core/DpEditor/libs/SegmentRangeChangePlugin.js +35 -0
  49. package/components/core/DpEditor/libs/editorAnonymize.js +66 -0
  50. package/components/core/DpEditor/libs/editorBuildSuggestion.js +269 -0
  51. package/components/core/DpEditor/libs/editorCustomDelete.js +32 -0
  52. package/components/core/DpEditor/libs/editorCustomImage.js +100 -0
  53. package/components/core/DpEditor/libs/editorCustomInsert.js +32 -0
  54. package/components/core/DpEditor/libs/editorCustomLink.js +46 -0
  55. package/components/core/DpEditor/libs/editorCustomMark.js +32 -0
  56. package/components/core/DpEditor/libs/editorInsertAtCursorPos.js +41 -0
  57. package/components/core/DpEditor/libs/editorObscure.js +60 -0
  58. package/components/core/DpEditor/libs/editorUnAnonymize.js +56 -0
  59. package/components/core/DpEditor/libs/handleWordPaste.js +360 -0
  60. package/components/core/DpEditor/libs/preventDrop.js +31 -0
  61. package/components/core/DpEditor/libs/preventKeyboardInput.js +27 -0
  62. package/components/core/DpEditor/libs/preventPaste.js +28 -0
  63. package/components/core/DpFlyout.vue +119 -0
  64. package/components/core/DpInlineNotification.vue +116 -0
  65. package/components/core/DpModal.vue +208 -0
  66. package/components/core/DpObscure.vue +29 -0
  67. package/components/core/DpPager.vue +139 -0
  68. package/components/core/DpProgressBar.vue +67 -0
  69. package/components/core/DpRegisterFlyout.vue +58 -0
  70. package/components/core/DpResettableInput.vue +140 -0
  71. package/components/core/DpSkeletonBox.vue +32 -0
  72. package/components/core/DpSlidebar.vue +86 -0
  73. package/components/core/DpSlidingPagination.vue +45 -0
  74. package/components/core/DpSplitButton.vue +77 -0
  75. package/components/core/DpSwitcher.vue +62 -0
  76. package/components/core/DpTableCardList/DpTableCard.vue +61 -0
  77. package/components/core/DpTableCardList/DpTableCardListHeader.vue +83 -0
  78. package/components/core/DpTabs/DpTab.vue +52 -0
  79. package/components/core/DpTabs/DpTabs.vue +165 -0
  80. package/components/core/DpTextWrapper.vue +65 -0
  81. package/components/core/DpToggleForm.vue +72 -0
  82. package/components/core/DpTooltipIcon.vue +52 -0
  83. package/components/core/DpTransitionExpand.vue +87 -0
  84. package/components/core/DpTreeList/DpTreeList.vue +334 -0
  85. package/components/core/DpTreeList/DpTreeListCheckbox.vue +79 -0
  86. package/components/core/DpTreeList/DpTreeListNode.vue +348 -0
  87. package/components/core/DpTreeList/DpTreeListToggle.vue +71 -0
  88. package/components/core/DpTreeList/utils/constants.js +14 -0
  89. package/components/core/DpUpload/DpUpload.vue +223 -0
  90. package/components/core/DpUpload/DpUploadFiles.vue +269 -0
  91. package/components/core/DpUpload/DpUploadedFile.vue +80 -0
  92. package/components/core/DpUpload/DpUploadedFileList.vue +56 -0
  93. package/components/core/DpUpload/utils/GetFileIdsByHash.js +42 -0
  94. package/components/core/DpUpload/utils/UppyTranslations.js +31 -0
  95. package/components/core/DpVideoPlayer.vue +115 -0
  96. package/components/core/HeightLimit.vue +121 -0
  97. package/components/core/MultistepNav.vue +89 -0
  98. package/components/core/form/DpCheckbox.vue +108 -0
  99. package/components/core/form/DpDateRangePicker.vue +186 -0
  100. package/components/core/form/DpDatepicker.vue +160 -0
  101. package/components/core/form/DpDatetimePicker.vue +194 -0
  102. package/components/core/form/DpFormRow.vue +79 -0
  103. package/components/core/form/DpMultiselect.vue +164 -0
  104. package/components/core/form/DpRadio.vue +128 -0
  105. package/components/core/form/DpSearchField.vue +110 -0
  106. package/components/core/form/DpSelect.vue +149 -0
  107. package/components/core/form/DpTextArea.vue +152 -0
  108. package/components/core/form/DpTimePicker.vue +374 -0
  109. package/components/core/form/DpToggle.vue +78 -0
  110. package/components/core/index.js +132 -0
  111. package/components/core/notify/DpNotifyContainer.vue +122 -0
  112. package/components/core/notify/DpNotifyMessage.vue +95 -0
  113. package/components/core/shared/DpStickyElement.vue +95 -0
  114. package/components/index.js +24 -0
  115. package/components/shared/translations.js +15 -0
  116. package/directives/CleanHtml/CleanHtml.js +50 -0
  117. package/directives/CleanHtml/CleanHtml.stories.mdx +64 -0
  118. package/directives/Tooltip/Tooltip.js +40 -0
  119. package/directives/Tooltip/Tooltip.stories.mdx +42 -0
  120. package/directives/index.js +17 -0
  121. package/lib/index.js +14 -0
  122. package/lib/prefixClass.js +47 -0
  123. package/mixins/index.js +14 -0
  124. package/mixins/prefixClassMixin.js +22 -0
  125. package/package.json +52 -0
  126. package/shared/props.js +86 -0
  127. package/style/index.css +7 -0
  128. package/tailwind.config.js +24 -0
  129. package/tokens/color.json +358 -0
  130. package/tokens/color.stories.mdx +45 -0
  131. package/tokens/fontSize.json +100 -0
  132. package/tokens/space.json +33 -0
  133. package/utils/lengthHint.js +69 -0
@@ -0,0 +1,28 @@
1
+ /**
2
+ * (c) 2010-present DEMOS E-Partizipation GmbH.
3
+ *
4
+ * This file is part of the package @demos-europe/demosplan-ui,
5
+ * for more information see the license file.
6
+ *
7
+ * All rights reserved
8
+ */
9
+
10
+ import { Extension, Plugin } from 'tiptap'
11
+
12
+ export default class preventPaste extends Extension {
13
+ get name () {
14
+ return 'PreventProp'
15
+ }
16
+
17
+ get plugins () {
18
+ return [
19
+ new Plugin({
20
+ props: {
21
+ handlePaste () {
22
+ return true
23
+ }
24
+ }
25
+ })
26
+ ]
27
+ }
28
+ }
@@ -0,0 +1,119 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <documentation>
11
+ <!--
12
+
13
+ The DpFlyout component renders a flyout that is intended to show stuff.
14
+
15
+ @improve use https://popper.js.org/docs/v2/ for positioning instead of basic css - or find
16
+ another way to make left/right offset dynamic.
17
+
18
+ -->
19
+ <usage variant="TBD">
20
+ </usage>
21
+ </documentation>
22
+
23
+ <template>
24
+ <span
25
+ class="o-flyout"
26
+ :class="{
27
+ 'o-flyout--left': align === 'left',
28
+ 'o-flyout--right': align === 'right',
29
+ 'o-flyout--padded': padded,
30
+ 'is-expanded': isExpanded,
31
+ 'o-flyout--menu': hasMenu
32
+ }"
33
+ v-click-outside="close"
34
+ data-cy="flyoutTrigger">
35
+ <button
36
+ :disabled="disabled"
37
+ type="button"
38
+ aria-haspopup="true"
39
+ class="o-flyout__trigger btn--blank o-link--default u-ph-0_25 line-height--2 whitespace--nowrap"
40
+ @click="toggle">
41
+ <slot name="trigger">
42
+ <i class="fa fa-ellipsis-h" />
43
+ </slot>
44
+ </button>
45
+ <div
46
+ class="o-flyout__content box-shadow-1"
47
+ data-cy="flyout">
48
+ <slot />
49
+ </div>
50
+ </span>
51
+ </template>
52
+
53
+ <script>
54
+ import ClickOutside from 'vue-click-outside'
55
+
56
+ export default {
57
+ name: 'DpFlyout',
58
+
59
+ directives: {
60
+ ClickOutside
61
+ },
62
+
63
+ props: {
64
+ align: {
65
+ required: false,
66
+ type: String,
67
+ default: 'right',
68
+ validator: (prop) => ['left', 'right'].includes(prop)
69
+ },
70
+
71
+ disabled: {
72
+ required: false,
73
+ type: Boolean,
74
+ default: false
75
+ },
76
+
77
+ hasMenu: {
78
+ required: false,
79
+ type: Boolean,
80
+ default: true
81
+ },
82
+
83
+ padded: {
84
+ required: false,
85
+ type: Boolean,
86
+ default: true
87
+ }
88
+ },
89
+
90
+ data () {
91
+ return {
92
+ isExpanded: false
93
+ }
94
+ },
95
+
96
+ methods: {
97
+ close () {
98
+ if (this.isExpanded === true) {
99
+ this.$emit('close')
100
+ this.isExpanded = false
101
+ }
102
+ },
103
+
104
+ toggle () {
105
+ this.isExpanded = !this.isExpanded
106
+
107
+ if (this.isExpanded) {
108
+ this.$emit('open')
109
+ } else {
110
+ this.$emit('close')
111
+ }
112
+ }
113
+ },
114
+
115
+ mounted () {
116
+ this.popupItem = this.$el
117
+ }
118
+ }
119
+ </script>
@@ -0,0 +1,116 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <template>
11
+ <div
12
+ v-if="isDismissed === false"
13
+ :class="`flash flash-${type} flex`">
14
+ <i
15
+ class="fa u-pr-0_25 line-height--1_4"
16
+ :class="iconClasses[type]"
17
+ aria-hidden="true" />
18
+ <div class="space-stack-xs">
19
+ <div
20
+ v-if="message"
21
+ v-html="message" />
22
+ <slot />
23
+ <button
24
+ v-if="dismissible"
25
+ class="btn--blank o-link--default weight--bold"
26
+ v-text="Translator.trans('hint.dismiss')"
27
+ @click="dismiss" />
28
+ </div>
29
+ </div>
30
+ <div
31
+ v-else
32
+ class="cf">
33
+ <button
34
+ :aria-label="Translator.trans('hint.show')"
35
+ class="btn--blank color--grey float--right"
36
+ @click="show">
37
+ <dp-icon
38
+ icon="info"
39
+ aria-hidden="true" />
40
+ </button>
41
+ </div>
42
+ </template>
43
+
44
+ <script>
45
+ import { DpIcon } from 'demosplan-ui/components'
46
+ import lscache from 'lscache'
47
+
48
+ export default {
49
+ name: 'DpInlineNotification',
50
+
51
+ components: {
52
+ DpIcon
53
+ },
54
+
55
+ props: {
56
+ /**
57
+ * A notification may be too prominent if permanently visible. In that case it can be dismissed.
58
+ * A small icon will take the place of the notification to bring it back if needed.
59
+ */
60
+ dismissible: {
61
+ type: Boolean,
62
+ required: false,
63
+ default: false
64
+ },
65
+
66
+ /**
67
+ * If set, the dismissed state will be preserved via localStorage.
68
+ */
69
+ dismissibleKey: {
70
+ type: String,
71
+ required: false,
72
+ default: null
73
+ },
74
+
75
+ message: {
76
+ type: String,
77
+ required: false,
78
+ default: null
79
+ },
80
+
81
+ type: {
82
+ type: String,
83
+ required: false,
84
+ default: 'error'
85
+ }
86
+ },
87
+
88
+ data () {
89
+ return {
90
+ iconClasses: {
91
+ confirm: 'fa-check',
92
+ error: 'fa-exclamation-circle',
93
+ info: 'fa-info-circle',
94
+ warning: 'fa-exclamation-triangle'
95
+ },
96
+ isDismissed: true
97
+ }
98
+ },
99
+
100
+ methods: {
101
+ dismiss () {
102
+ this.isDismissed = true
103
+ this.dismissibleKey && lscache.set(this.dismissibleKey, Date.now())
104
+ },
105
+
106
+ show () {
107
+ this.isDismissed = false
108
+ this.dismissibleKey && lscache.remove(this.dismissibleKey)
109
+ }
110
+ },
111
+
112
+ mounted () {
113
+ this.isDismissed = (this.dismissible && this.dismissibleKey) ? !!lscache.get(this.dismissibleKey) : false
114
+ }
115
+ }
116
+ </script>
@@ -0,0 +1,208 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <template>
11
+ <div
12
+ :class="prefixClass('o-modal')"
13
+ @keydown="checkKeyEvent">
14
+ <transition
15
+ name="content"
16
+ appear
17
+ @enter="preventScroll">
18
+ <aside
19
+ v-if="isOpenModal"
20
+ :aria-label="ariaLabel"
21
+ :class="prefixClass('o-modal__content ' + contentClasses)"
22
+ role="dialog">
23
+ <button
24
+ :class="prefixClass('btn--blank o-link--default position--absolute u-right-0 u-p-0_5')"
25
+ :aria-label="Translator.trans('close.window')"
26
+ :title="Translator.trans('close.window')"
27
+ @click.prevent.stop="toggle()">
28
+ <dp-icon icon="close" />
29
+ </button>
30
+ <div :class="prefixClass('o-modal__body ' + contentBodyClasses)">
31
+ <h2
32
+ :class="prefixClass('font-size-h1 border--bottom u-pb-0_25 ' + contentHeaderClasses)"
33
+ v-if="hasHeader">
34
+ <slot name="header" />
35
+ </h2>
36
+ <slot name="default" />
37
+ </div>
38
+ </aside>
39
+ </transition>
40
+ <transition
41
+ name="backdrop"
42
+ appear
43
+ @after-leave="preventScroll(false)">
44
+ <div
45
+ v-if="isOpenModal"
46
+ @click.prevent.stop="toggle()"
47
+ :class="prefixClass('o-modal__backdrop')" />
48
+ </transition>
49
+ </div>
50
+ </template>
51
+
52
+ <script>
53
+ import { DpIcon } from 'demosplan-ui/components'
54
+ import { prefixClassMixin } from 'demosplan-ui/mixins'
55
+
56
+ export default {
57
+ name: 'DpModal',
58
+
59
+ components: {
60
+ DpIcon
61
+ },
62
+
63
+ mixins: [prefixClassMixin],
64
+
65
+ props: {
66
+ ariaLabel: {
67
+ required: false,
68
+ type: String,
69
+ default: ''
70
+ },
71
+
72
+ contentBodyClasses: {
73
+ required: false,
74
+ type: String,
75
+ default: ''
76
+ },
77
+
78
+ contentClasses: {
79
+ required: false,
80
+ type: String,
81
+ default: ''
82
+ },
83
+
84
+ contentHeaderClasses: {
85
+ required: false,
86
+ type: String,
87
+ default: ''
88
+ },
89
+
90
+ // Required when toggling modal with toggleByEvent()
91
+ modalId: {
92
+ required: false,
93
+ type: String,
94
+ default: ''
95
+ }
96
+ },
97
+
98
+ data () {
99
+ return {
100
+ isOpenModal: false,
101
+ lastFocusedElement: '',
102
+ focusableElements: []
103
+ }
104
+ },
105
+
106
+ computed: {
107
+ hasHeader () {
108
+ return typeof this.$slots.header !== 'undefined'
109
+ }
110
+ },
111
+
112
+ methods: {
113
+ getFocusableElements () {
114
+ this.focusableElements = [...this.$el.querySelectorAll('a, button:not([disabled]), input, textarea, select, details, [tabindex]:not([tabindex="-1"])')].filter(el => this.isElementVisible(el))
115
+ },
116
+
117
+ isElementVisible (el) {
118
+ const isInDom = el.offsetParent !== null
119
+ const style = window.getComputedStyle(el)
120
+ const isDisplayed = style.display !== 'none' && style.opacity !== '0'
121
+ return isInDom && isDisplayed
122
+ },
123
+
124
+ toggleByEvent (modalId) {
125
+ // Do not execute without a specified modalId to prevent unintentional toggling of multiple modals
126
+ if (typeof modalId === 'undefined') {
127
+ return
128
+ }
129
+ // Check if event specifies the correct modal instance
130
+ if (this.modalId === modalId) {
131
+ this.toggle()
132
+ }
133
+ },
134
+
135
+ toggle () {
136
+ this.isOpenModal = (this.isOpenModal === false)
137
+ this.$emit('modal:toggled', this.isOpenModal)
138
+ if (this.isOpenModal === true) {
139
+ this.lastFocusedElement = document.activeElement
140
+ // On toggle get all focusable elements and focus the first one (after everything is rendered)
141
+ this.$nextTick(() => {
142
+ this.getFocusableElements()
143
+ if (this.focusableElements.length > 0) {
144
+ this.focusableElements[0].focus({ preventScroll: true })
145
+ }
146
+ })
147
+ } else {
148
+ this.lastFocusedElement.focus()
149
+ }
150
+ },
151
+
152
+ /**
153
+ * By setting the html element to overflow: hidden, content behind the opened modal is locked for scrolling.
154
+ * To prevent page jumps when the scroll bar disappears, a padding is put onto the body element.
155
+ *
156
+ * When toggling the modal in, this can be done immediately. When removing the modal, we have to wait for the
157
+ * transition to finish, otherwise the modal jumps a little to the left when the "real scrollbar" appears again.
158
+ * The @after-leave hook is called from the backdrop because the transition applied to it is slightly longer.
159
+ *
160
+ * @param {boolean} toggleIn
161
+ */
162
+ preventScroll (toggleIn) {
163
+ const htmlElement = document.querySelector('html')
164
+ const bodyElement = document.querySelector('body')
165
+ if (toggleIn) {
166
+ htmlElement.style.overflow = 'hidden'
167
+ bodyElement.style.overflowY = 'scroll'
168
+ } else {
169
+ htmlElement.style.overflow = null
170
+ bodyElement.style.overflowY = null
171
+ }
172
+ },
173
+
174
+ checkKeyEvent (event) {
175
+ // Close modal and return early if escape
176
+ if (event.key === 'Escape') {
177
+ this.toggle()
178
+ } else if (event.key === 'Tab') {
179
+ event.preventDefault()
180
+ const eventTargetIndex = this.focusableElements.findIndex(el => el === event.target)
181
+ const last = this.focusableElements.length - 1
182
+ if (this.focusableElements.length < 2) {
183
+ // Do nothing if only 1 or no elements to focus
184
+ } else if (event.shiftKey === false && event.target === this.focusableElements[last]) {
185
+ // If last element was previously focused, on tab jump to the first element
186
+ this.focusableElements[0].focus()
187
+ } else if (event.shiftKey === true && event.target === this.focusableElements[0]) {
188
+ // If first element was focused, on tab+shift focus the last element
189
+ this.focusableElements[last].focus()
190
+ } else {
191
+ const idxToFocus = event.shiftKey ? eventTargetIndex - 1 : eventTargetIndex + 1
192
+ this.focusableElements[idxToFocus].focus()
193
+ }
194
+ }
195
+ }
196
+ },
197
+
198
+ mounted () {
199
+ this.$root.$on('modal:toggle', (modalId) => this.toggleByEvent(modalId))
200
+ },
201
+
202
+ updated () {
203
+ // When component is re-rendered, we have to collect all focusable elements again, as new ones may have appeared
204
+ this.$nextTick(() => this.getFocusableElements())
205
+ }
206
+
207
+ }
208
+ </script>
@@ -0,0 +1,29 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <template>
11
+ <span
12
+ :class="obscureClass"
13
+ :title="Translator.trans('obscure.title')">
14
+ <slot />
15
+ </span>
16
+ </template>
17
+
18
+ <script>
19
+ export default {
20
+ name: 'DpObscure',
21
+
22
+ computed: {
23
+ obscureClass () {
24
+ return (hasPermission('feature_obscure_text')) ? 'u-obscure' : ''
25
+ }
26
+ }
27
+
28
+ }
29
+ </script>
@@ -0,0 +1,139 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <documentation>
11
+ <!--
12
+ This is a wrapper for the dp-sliding-pagination component that adds a itemsPerPage Box
13
+ -->
14
+ <usage>
15
+ <dp-pager
16
+ current-page="pagination.current_page"
17
+ total-pages="pagination.total_pages"
18
+ total-items="pagination.total"
19
+ per-page="pagination.count"
20
+ limits="pagination.limits"
21
+ @page-change="handlePageChange"
22
+ @size-change="handleSizeChange"
23
+ ></dp-pager>
24
+ </usage>
25
+ </documentation>
26
+
27
+ <template>
28
+ <div class="c-pager__dropdown">
29
+ <label
30
+ class="c-pager__dropdown-label u-m-0 u-p-0 weight--normal display--inline-block"
31
+ :aria-label="Translator.trans('pager.amount.multiple.label', { results: totalItems, items: Translator.trans('pager.amount.multiple.items') })">
32
+ <span aria-hidden="true">
33
+ {{ Translator.trans('pager.amount.multiple.show') }}
34
+ </span>
35
+ <div
36
+ class="display--inline-block"
37
+ v-if="totalItems > Math.min(...limits)">
38
+ <dp-multiselect
39
+ class="display--inline-block"
40
+ v-model="itemsPerPage"
41
+ @select="handleSizeChange"
42
+ :searchable="false"
43
+ selected-label=""
44
+ :options="filteredLimits" />
45
+ </div>
46
+ <span v-else>{{ totalItems }}</span>
47
+ <span aria-hidden="true">
48
+ {{ Translator.trans('pager.amount.multiple.of') }}
49
+ <span data-cy="totalItems">{{ totalItems }}</span>
50
+ {{ Translator.trans('pager.amount.multiple.items') }}
51
+ </span>
52
+ </label>
53
+ <dp-sliding-pagination
54
+ v-if="totalItems > Math.min(...limits)"
55
+ class="display--inline-block"
56
+ :current="currentPage"
57
+ :total="totalPages || 1"
58
+ @page-change="handlePageChange" />
59
+ </div>
60
+ </template>
61
+
62
+ <script>
63
+ import DpMultiselect from './form/DpMultiselect'
64
+ import DpSlidingPagination from './DpSlidingPagination'
65
+
66
+ export default {
67
+ name: 'DpPager',
68
+
69
+ components: {
70
+ DpSlidingPagination,
71
+ DpMultiselect
72
+ },
73
+
74
+ props: {
75
+ currentPage: {
76
+ required: false,
77
+ type: Number,
78
+ default: 1
79
+ },
80
+
81
+ totalItems: {
82
+ required: false,
83
+ type: Number,
84
+ default: 1
85
+ },
86
+
87
+ totalPages: {
88
+ required: false,
89
+ type: Number,
90
+ default: 1
91
+ },
92
+
93
+ perPage: {
94
+ required: false,
95
+ type: Number,
96
+ default: 1
97
+ },
98
+
99
+ limits: {
100
+ required: false,
101
+ type: Array,
102
+ default: () => []
103
+ }
104
+ },
105
+
106
+ data () {
107
+ return {
108
+ itemsPerPage: this.perPage <= this.totalItems ? this.perPage : this.totalItems
109
+ }
110
+ },
111
+
112
+ computed: {
113
+ filteredLimits () {
114
+ const filtered = this.limits.filter(limit => limit <= this.totalItems)
115
+
116
+ if (filtered.length < this.limits.length && this.totalItems > filtered[filtered.length - 1]) {
117
+ filtered.push(this.totalItems)
118
+ }
119
+
120
+ if (filtered.includes(this.itemsPerPage) === false) {
121
+ filtered.push(this.itemsPerPage)
122
+ }
123
+ filtered.sort((a, b) => a - b)
124
+
125
+ return filtered
126
+ }
127
+ },
128
+
129
+ methods: {
130
+ handlePageChange (newPage) {
131
+ this.$emit('page-change', newPage)
132
+ },
133
+
134
+ handleSizeChange (selectedOption) {
135
+ this.$emit('size-change', parseInt(selectedOption))
136
+ }
137
+ }
138
+ }
139
+ </script>
@@ -0,0 +1,67 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <template>
11
+ <div class="c-progress-bar">
12
+ <template v-if="indeterminate">
13
+ <div class="u-mb-0_25 weight--bold">
14
+ {{ label }}
15
+ </div>
16
+
17
+ <div class="c-progress-bar__line is-animated" />
18
+ </template>
19
+
20
+ <template v-else>
21
+ <div class="u-mb-0_25 weight--bold">
22
+ {{ label }}
23
+ </div>
24
+
25
+ <div class="bg-color--grey-light-2">
26
+ <div
27
+ class="u-mb-0_25 c-progress-bar__line"
28
+ :style="style" />
29
+ </div>
30
+ <span>
31
+ {{ percentage }}%
32
+ </span>
33
+ </template>
34
+ </div>
35
+ </template>
36
+
37
+ <script>
38
+ export default {
39
+ name: 'DpProgressBar',
40
+
41
+ props: {
42
+ indeterminate: {
43
+ type: Boolean,
44
+ required: false,
45
+ default: false
46
+ },
47
+
48
+ label: {
49
+ type: String,
50
+ required: false,
51
+ default: ''
52
+ },
53
+
54
+ percentage: {
55
+ type: Number,
56
+ required: false,
57
+ default: 0
58
+ }
59
+ },
60
+
61
+ computed: {
62
+ style () {
63
+ return 'width: ' + this.percentage + '%;'
64
+ }
65
+ }
66
+ }
67
+ </script>