@antify/ui-module 1.2.1 → 1.4.0

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 (36) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/AntTooltip.vue +69 -63
  3. package/dist/runtime/components/__stories/AntTooltip.stories.d.ts +5 -0
  4. package/dist/runtime/components/__stories/AntTooltip.stories.mjs +33 -11
  5. package/dist/runtime/components/buttons/AntActionButton.vue +63 -0
  6. package/dist/runtime/components/buttons/AntButton.vue +3 -3
  7. package/dist/runtime/components/buttons/AntCreateButton.vue +23 -14
  8. package/dist/runtime/components/buttons/AntDeleteButton.vue +23 -12
  9. package/dist/runtime/components/buttons/AntSaveAndNewButton.vue +24 -14
  10. package/dist/runtime/components/buttons/AntSaveButton.vue +23 -11
  11. package/dist/runtime/components/buttons/__stories/AntActionButton.stories.d.ts +11 -0
  12. package/dist/runtime/components/buttons/__stories/AntActionButton.stories.mjs +79 -0
  13. package/dist/runtime/components/buttons/__stories/AntCreateButton.stories.d.ts +1 -0
  14. package/dist/runtime/components/buttons/__stories/AntCreateButton.stories.mjs +9 -0
  15. package/dist/runtime/components/buttons/__stories/AntDeleteButton.stories.d.ts +1 -0
  16. package/dist/runtime/components/buttons/__stories/AntDeleteButton.stories.mjs +9 -0
  17. package/dist/runtime/components/buttons/__stories/AntSaveAndNewButton.stories.d.ts +1 -0
  18. package/dist/runtime/components/buttons/__stories/AntSaveAndNewButton.stories.mjs +9 -0
  19. package/dist/runtime/components/buttons/__stories/AntSaveButton.stories.d.ts +1 -0
  20. package/dist/runtime/components/buttons/__stories/AntSaveButton.stories.mjs +9 -0
  21. package/dist/runtime/components/crud/AntCrudDetailActions.vue +10 -3
  22. package/dist/runtime/components/crud/AntCrudDetailNav.vue +21 -15
  23. package/dist/runtime/components/crud/AntCrudTableFilter.vue +35 -33
  24. package/dist/runtime/utils.d.ts +6 -0
  25. package/dist/runtime/utils.mjs +21 -0
  26. package/package.json +1 -1
  27. package/src/runtime/components/AntTooltip.vue +69 -63
  28. package/src/runtime/components/buttons/AntActionButton.vue +63 -0
  29. package/src/runtime/components/buttons/AntButton.vue +3 -3
  30. package/src/runtime/components/buttons/AntCreateButton.vue +23 -14
  31. package/src/runtime/components/buttons/AntDeleteButton.vue +23 -12
  32. package/src/runtime/components/buttons/AntSaveAndNewButton.vue +24 -14
  33. package/src/runtime/components/buttons/AntSaveButton.vue +23 -11
  34. package/src/runtime/components/crud/AntCrudDetailActions.vue +10 -3
  35. package/src/runtime/components/crud/AntCrudDetailNav.vue +21 -15
  36. package/src/runtime/components/crud/AntCrudTableFilter.vue +35 -33
package/dist/module.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "ui-module",
3
3
  "configKey": "uiModule",
4
- "version": "1.2.1"
4
+ "version": "1.4.0"
5
5
  }
@@ -3,78 +3,80 @@ import {computed, onMounted, ref} from 'vue';
3
3
  import {handleEnumValidation} from '../handler';
4
4
  import {InputColorType, Position} from '../enums';
5
5
  import {classesToObjectSyntax} from '../utils';
6
+ import {hasSlotContent} from '../utils';
6
7
 
7
8
  const props = withDefaults(defineProps<{
8
- content?: string,
9
- position?: Position,
10
- tooltipClasses?: string | Record<string, boolean>,
11
- colorType?: InputColorType
9
+ position?: Position
10
+ tooltipClasses?: string | Record<string, boolean>
11
+ colorType?: InputColorType
12
+ expanded?: boolean
12
13
  }>(), {
13
- position: Position.left,
14
- tooltipClasses: '',
15
- colorType: InputColorType.base
14
+ position: Position.left,
15
+ tooltipClasses: '',
16
+ colorType: InputColorType.base,
17
+ expanded: false
16
18
  });
17
19
  const visible = ref(false);
18
20
  const _tooltipClasses = computed(() => ({
19
- 'absolute w-max inline-flex': true,
20
- // Position
21
- 'bottom-full pb-3.5': props.position === Position.top,
22
- 'top-full pt-3.5': props.position === Position.bottom,
23
- 'right-full pr-3.5': props.position === Position.left,
24
- 'left-full pl-3.5': props.position === Position.right,
25
- ...classesToObjectSyntax(props.tooltipClasses)
21
+ 'absolute w-max inline-flex': true,
22
+ // Position
23
+ 'bottom-full pb-3.5': props.position === Position.top,
24
+ 'top-full pt-3.5': props.position === Position.bottom,
25
+ 'right-full pr-3.5': props.position === Position.left,
26
+ 'left-full pl-3.5': props.position === Position.right,
27
+ ...classesToObjectSyntax(props.tooltipClasses)
26
28
  }));
27
29
  const classes = computed(() => ({
28
- 'z-10 absolute flex': true,
29
- 'top-0 left-0 right-0 -m-[2px] justify-center': props.position === Position.bottom,
30
- 'bottom-0 left-0 right-0 -m-[2px] justify-center': props.position === Position.top,
31
- 'top-0 left-0 bottom-0 -ml-[2.2px] items-center': props.position === Position.right,
32
- 'top-0 right-0 bottom-0 -mr-[2.2px] items-center': props.position === Position.left,
30
+ 'z-10 absolute flex': true,
31
+ 'top-0 left-0 right-0 -m-[2px] justify-center': props.position === Position.bottom,
32
+ 'bottom-0 left-0 right-0 -m-[2px] justify-center': props.position === Position.top,
33
+ 'top-0 left-0 bottom-0 -ml-[2.2px] items-center': props.position === Position.right,
34
+ 'top-0 right-0 bottom-0 -mr-[2.2px] items-center': props.position === Position.left,
33
35
  }));
34
36
  const itemContainerClasses = computed(() => ({
35
- 'relative flex items-center': true,
36
- 'justify-center': props.position === Position.bottom,
37
- 'justify-center rotate-180': props.position === Position.top,
38
- 'justify-center -rotate-90': props.position === Position.right,
39
- 'justify-center rotate-90': props.position === Position.left,
37
+ 'relative flex items-center': true,
38
+ 'justify-center': props.position === Position.bottom,
39
+ 'justify-center rotate-180': props.position === Position.top,
40
+ 'justify-center -rotate-90': props.position === Position.right,
41
+ 'justify-center rotate-90': props.position === Position.left,
40
42
  }));
41
43
  const contentClasses = computed(() => {
42
- const variants: Record<InputColorType, string> = {
43
- [InputColorType.base]: 'text-neutral-50-font bg-neutral-50 border-neutral-300',
44
- [InputColorType.danger]: 'text-danger-500-font bg-danger-500 border-danger-500',
45
- [InputColorType.info]: 'text-info-500-font bg-info-500 border-info-500',
46
- [InputColorType.success]: 'text-success-500-font bg-success-500 border-success-500',
47
- [InputColorType.warning]: 'text-warning-500-font bg-warning-500 border-warning-500',
48
- };
44
+ const variants: Record<InputColorType, string> = {
45
+ [InputColorType.base]: 'text-neutral-50-font bg-neutral-50 border-neutral-300',
46
+ [InputColorType.danger]: 'text-danger-500-font bg-danger-500 border-danger-500',
47
+ [InputColorType.info]: 'text-info-500-font bg-info-500 border-info-500',
48
+ [InputColorType.success]: 'text-success-500-font bg-success-500 border-success-500',
49
+ [InputColorType.warning]: 'text-warning-500-font bg-warning-500 border-warning-500',
50
+ };
49
51
 
50
- return {[variants[props.colorType]]: true};
52
+ return {[variants[props.colorType]]: true};
51
53
  });
52
54
  const svgPathClasses = computed(() => {
53
- const variants: Record<InputColorType, string> = {
54
- [InputColorType.base]: 'fill-neutral-50 stroke-neutral-50',
55
- [InputColorType.danger]: 'fill-danger-500 stroke-danger-500',
56
- [InputColorType.info]: 'fill-info-500 stroke-info-500',
57
- [InputColorType.success]: 'fill-success-500 stroke-success-500',
58
- [InputColorType.warning]: 'fill-warning-500 stroke-warning-500',
59
- };
55
+ const variants: Record<InputColorType, string> = {
56
+ [InputColorType.base]: 'fill-neutral-50 stroke-neutral-50',
57
+ [InputColorType.danger]: 'fill-danger-500 stroke-danger-500',
58
+ [InputColorType.info]: 'fill-info-500 stroke-info-500',
59
+ [InputColorType.success]: 'fill-success-500 stroke-success-500',
60
+ [InputColorType.warning]: 'fill-warning-500 stroke-warning-500',
61
+ };
60
62
 
61
- return {[variants[props.colorType]]: true};
63
+ return {[variants[props.colorType]]: true};
62
64
  });
63
65
  const arrowSvgPathClasses = computed(() => {
64
- const variants: Record<InputColorType, string> = {
65
- [InputColorType.base]: 'stroke-neutral-300',
66
- [InputColorType.danger]: 'stroke-danger-500',
67
- [InputColorType.info]: 'stroke-info-500',
68
- [InputColorType.success]: 'stroke-success-500',
69
- [InputColorType.warning]: 'stroke-warning-500',
70
- };
66
+ const variants: Record<InputColorType, string> = {
67
+ [InputColorType.base]: 'stroke-neutral-300',
68
+ [InputColorType.danger]: 'stroke-danger-500',
69
+ [InputColorType.info]: 'stroke-info-500',
70
+ [InputColorType.success]: 'stroke-success-500',
71
+ [InputColorType.warning]: 'stroke-warning-500',
72
+ };
71
73
 
72
- return {[variants[props.colorType]]: true};
74
+ return {[variants[props.colorType]]: true};
73
75
  });
74
76
 
75
77
  onMounted(() => {
76
- handleEnumValidation(props.position, Position, 'Position')
77
- handleEnumValidation(props.colorType, InputColorType, 'colorType')
78
+ handleEnumValidation(props.position, Position, 'Position')
79
+ handleEnumValidation(props.colorType, InputColorType, 'colorType')
78
80
  });
79
81
 
80
82
  /**
@@ -84,33 +86,37 @@ onMounted(() => {
84
86
  const delayVisible = ref(visible.value);
85
87
 
86
88
  function onMouseOver() {
87
- delayVisible.value = true;
89
+ delayVisible.value = true;
88
90
 
89
- setTimeout(() => {
90
- if (delayVisible.value) {
91
- visible.value = true
92
- }
93
- }, 300)
91
+ setTimeout(() => {
92
+ if (delayVisible.value) {
93
+ visible.value = true
94
+ }
95
+ }, 300)
94
96
  }
95
97
 
96
98
  function onMouseLeave() {
97
- delayVisible.value = false
98
- visible.value = false
99
+ delayVisible.value = false
100
+ visible.value = false
99
101
  }
100
102
  </script>
101
103
 
102
104
  <template>
103
105
  <div
104
- class="relative inline-flex justify-center items-center"
106
+ class="relative justify-center items-center"
107
+ :class="{'flex w-full': props.expanded, 'inline-flex': !props.expanded}"
105
108
  data-e2e="tooltip"
106
109
  @mouseover="onMouseOver"
107
110
  @mouseleave="onMouseLeave"
108
111
  >
109
- <slot/>
112
+ <slot />
110
113
 
111
- <div v-if="visible" :class="_tooltipClasses">
114
+ <div
115
+ v-if="visible && hasSlotContent($slots.content)"
116
+ :class="_tooltipClasses"
117
+ >
112
118
  <div
113
- class="shadow-lg text-sm relative inline-flex flex-col relative"
119
+ class="shadow-lg text-sm relative"
114
120
  >
115
121
  <div
116
122
  :class="classes"
@@ -157,7 +163,7 @@ function onMouseLeave() {
157
163
  class="p-2.5 rounded-md border"
158
164
  :class="contentClasses"
159
165
  >
160
- <slot name="content"/>
166
+ <slot name="content" />
161
167
  </div>
162
168
  </div>
163
169
  </div>
@@ -4,3 +4,8 @@ declare const meta: Meta<typeof AntTooltip>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof AntTooltip>;
6
6
  export declare const Docs: Story;
7
+ /**
8
+ * Make sure, no tooltip get shown if no content is provided.
9
+ */
10
+ export declare const WithoutContent: Story;
11
+ export declare const Expanded: Story;
@@ -25,19 +25,41 @@ export const Docs = {
25
25
  return { args };
26
26
  },
27
27
  template: `
28
- <div class="p-32 flex justify-center items-center">
29
- <AntTooltip v-bind="args">
30
- <template #content>Lorem ipsum dolor sit amet <br/> foo</template>
31
- <template #default>
32
- <span class="text-primary-500 bg-danger-500">
33
- Hover me
34
- </span>
35
- </template>
36
- </AntTooltip>
37
- </div>
38
- `
28
+ <div class="p-32 flex justify-center items-center">
29
+ <AntTooltip v-bind="args">
30
+ <template #content>Lorem ipsum dolor sit amet <br/> foo</template>
31
+ <template #default>
32
+ <AntButton readonly filled expanded>Hover me</AntButton>
33
+ </template>
34
+ </AntTooltip>
35
+ </div>
36
+ `
39
37
  }),
40
38
  args: {
41
39
  position: Position.top
42
40
  }
43
41
  };
42
+ export const WithoutContent = {
43
+ render: (args) => ({
44
+ components: { AntTooltip, AntButton },
45
+ setup() {
46
+ return { args };
47
+ },
48
+ template: `
49
+ <div class="p-32 flex justify-center items-center">
50
+ <AntTooltip v-bind="args">
51
+ <AntButton readonly filled expanded>Hover me</AntButton>
52
+
53
+ <template #content></template>
54
+ </AntTooltip>
55
+ </div>
56
+ `
57
+ }),
58
+ args: {}
59
+ };
60
+ export const Expanded = {
61
+ render: Docs.render,
62
+ args: {
63
+ expanded: true
64
+ }
65
+ };
@@ -0,0 +1,63 @@
1
+ <script lang="ts" setup>
2
+ /**
3
+ * This button is used for everything what is the primary
4
+ * action like save, confirm, create, etc.
5
+ */
6
+ import {Grouped} from '../../enums/Grouped.enum';
7
+ import {Size} from '../../enums/Size.enum';
8
+ import {ColorType, InputColorType} from '../../enums/ColorType.enum';
9
+ import {Position} from '../../enums/Position.enum';
10
+ import AntButton from './AntButton.vue';
11
+ import AntTooltip from '../AntTooltip.vue';
12
+
13
+ defineEmits(['click', 'blur']);
14
+ withDefaults(
15
+ defineProps<{
16
+ size?: Size;
17
+ disabled?: boolean;
18
+ grouped?: Grouped;
19
+ colorType?: ColorType;
20
+ skeleton?: boolean;
21
+ expanded?: boolean;
22
+ filled?: boolean;
23
+ hasPermission?: boolean;
24
+ invalidPermissionTooltipPosition?: Position;
25
+ }>(), {
26
+ colorType: ColorType.primary,
27
+ hasPermission: true,
28
+ filled: true
29
+ }
30
+ )
31
+ </script>
32
+
33
+ <template>
34
+ <AntTooltip
35
+ :expanded="expanded"
36
+ :position="invalidPermissionTooltipPosition"
37
+ :color-type="InputColorType.info"
38
+ >
39
+ <slot name="button">
40
+ <AntButton
41
+ :size="size"
42
+ :disabled="disabled || !hasPermission"
43
+ :grouped="grouped"
44
+ :skeleton="skeleton"
45
+ :expanded="expanded"
46
+ :color-type="colorType"
47
+ :filled="filled"
48
+ data-e2e="action-button"
49
+ @click="$emit('click')"
50
+ @blur="$emit('blur')"
51
+ >
52
+ <slot />
53
+ </AntButton>
54
+ </slot>
55
+
56
+ <template
57
+ v-if="!hasPermission && !skeleton"
58
+ #content
59
+ >
60
+ <slot name="invalidPermissionTooltipContent" />
61
+ </template>
62
+ </AntTooltip>
63
+ </template>
@@ -102,7 +102,7 @@ const classes = computed(() => {
102
102
  return {
103
103
  'transition-all inline-flex items-center justify-center relative font-medium': true,
104
104
  'focus:z-10': true,
105
- 'active:shadow-[inset_0_4px_4px_rgba(0,0,0,0.25)]': !props.readonly,
105
+ 'active:shadow-[inset_0_4px_4px_rgba(0,0,0,0.25)]': !hasAction.value,
106
106
  'py-1.5 px-2.5 text-xs gap-1': props.size === Size.sm,
107
107
  'py-2.5 px-3.5 text-sm gap-2.5': props.size === Size.md,
108
108
  'disabled:opacity-50 disabled:cursor-not-allowed': true,
@@ -115,9 +115,9 @@ const classes = computed(() => {
115
115
  ...groupedClassList.value,
116
116
  [variants[props.colorType]]: true,
117
117
  [notFilledVariants[props.colorType]]: !props.filled,
118
- [notFilledHoverVariants[props.colorType]]: !props.filled && !props.readonly,
118
+ [notFilledHoverVariants[props.colorType]]: !props.filled && !hasAction.value,
119
119
  [filledVariants[props.colorType]]: props.filled,
120
- [filledHoverVariants[props.colorType]]: props.filled && !props.readonly,
120
+ [filledHoverVariants[props.colorType]]: props.filled && !hasAction.value,
121
121
  };
122
122
  });
123
123
  const iconColor = computed(() => {
@@ -1,32 +1,41 @@
1
1
  <script lang="ts" setup>
2
2
  import {Grouped} from '../../enums/Grouped.enum';
3
3
  import {Size} from '../../enums/Size.enum';
4
- import {ColorType} from '../../enums/ColorType.enum';
5
- import AntButton from './AntButton.vue';
4
+ import AntActionButton from './AntActionButton.vue';
5
+ import {Position} from '../../enums';
6
6
 
7
7
  defineEmits(['click', 'blur']);
8
- defineProps<{
9
- size?: Size;
10
- disabled?: boolean;
11
- grouped?: Grouped;
12
- skeleton?: boolean;
13
- expanded?: boolean;
14
- }>()
8
+ withDefaults(defineProps<{
9
+ size?: Size;
10
+ disabled?: boolean;
11
+ grouped?: Grouped;
12
+ skeleton?: boolean;
13
+ expanded?: boolean;
14
+ canCreate?: boolean;
15
+ invalidPermissionTooltipPosition?: Position;
16
+ }>(), {
17
+ canCreate: true
18
+ });
15
19
  </script>
16
20
 
17
21
  <template>
18
- <AntButton
22
+ <AntActionButton
19
23
  :size="size"
20
24
  :disabled="disabled"
21
25
  :grouped="grouped"
22
26
  :skeleton="skeleton"
23
27
  :expanded="expanded"
24
- :color-type="ColorType.primary"
25
- filled
28
+ :has-permission="canCreate"
29
+ :invalid-permission-tooltip-position="invalidPermissionTooltipPosition"
26
30
  data-e2e="create-button"
27
31
  @click="$emit('click')"
28
32
  @blur="$emit('blur')"
29
33
  >
30
- Create
31
- </AntButton>
34
+ <template #default>Create</template>
35
+
36
+ <template #invalidPermissionTooltipContent>
37
+ You have no permission to create new entries.<br>
38
+ Please contact your administrator.
39
+ </template>
40
+ </AntActionButton>
32
41
  </template>
@@ -2,31 +2,42 @@
2
2
  import {Grouped} from '../../enums/Grouped.enum';
3
3
  import {Size} from '../../enums/Size.enum';
4
4
  import {ColorType} from '../../enums/ColorType.enum';
5
- import AntButton from './AntButton.vue';
5
+ import AntActionButton from './AntActionButton.vue';
6
+ import {Position} from '../../enums';
6
7
 
7
8
  defineEmits(['click', 'blur']);
8
- defineProps<{
9
- size?: Size;
10
- disabled?: boolean;
11
- grouped?: Grouped;
12
- skeleton?: boolean;
13
- expanded?: boolean;
14
- }>()
9
+ withDefaults(defineProps<{
10
+ size?: Size;
11
+ disabled?: boolean;
12
+ grouped?: Grouped;
13
+ skeleton?: boolean;
14
+ expanded?: boolean;
15
+ canDelete?: boolean;
16
+ invalidPermissionTooltipPosition?: Position;
17
+ }>(), {
18
+ canDelete: true
19
+ })
15
20
  </script>
16
21
 
17
22
  <template>
18
- <AntButton
23
+ <AntActionButton
19
24
  :size="size"
20
25
  :disabled="disabled"
21
26
  :grouped="grouped"
22
27
  :skeleton="skeleton"
23
28
  :expanded="expanded"
24
29
  :color-type="ColorType.danger"
25
- filled
30
+ :has-permission="canDelete"
31
+ :invalid-permission-tooltip-position="invalidPermissionTooltipPosition"
26
32
  data-e2e="delete-button"
27
33
  @click="$emit('click')"
28
34
  @blur="$emit('blur')"
29
35
  >
30
- Delete
31
- </AntButton>
36
+ <template #default>Delete</template>
37
+
38
+ <template #invalidPermissionTooltipContent>
39
+ You have no permission to delete this entry.<br>
40
+ Please contact your administrator.
41
+ </template>
42
+ </AntActionButton>
32
43
  </template>
@@ -1,32 +1,42 @@
1
1
  <script lang="ts" setup>
2
2
  import {Grouped} from '../../enums/Grouped.enum';
3
3
  import {Size} from '../../enums/Size.enum';
4
- import {ColorType} from '../../enums/ColorType.enum';
5
- import AntButton from './AntButton.vue';
4
+ import AntActionButton from './AntActionButton.vue';
5
+ import {Position} from '../../enums';
6
6
 
7
7
  defineEmits(['click', 'blur']);
8
- defineProps<{
9
- size?: Size;
10
- disabled?: boolean;
11
- grouped?: Grouped;
12
- skeleton?: boolean;
13
- expanded?: boolean;
14
- }>()
8
+ withDefaults(defineProps<{
9
+ size?: Size;
10
+ disabled?: boolean;
11
+ grouped?: Grouped;
12
+ skeleton?: boolean;
13
+ expanded?: boolean;
14
+ canSave?: boolean;
15
+ invalidPermissionTooltipPosition?: Position;
16
+ }>(), {
17
+ canSave: true
18
+ });
15
19
  </script>
16
20
 
17
21
  <template>
18
- <AntButton
22
+ <AntActionButton
19
23
  :size="size"
20
24
  :disabled="disabled"
21
25
  :grouped="grouped"
22
26
  :skeleton="skeleton"
23
27
  :expanded="expanded"
24
- :color-type="ColorType.primary"
25
- filled
28
+ :filled="false"
29
+ :has-permission="canSave"
30
+ :invalid-permission-tooltip-position="invalidPermissionTooltipPosition"
26
31
  data-e2e="save-and-new-button"
27
32
  @click="$emit('click')"
28
33
  @blur="$emit('blur')"
29
34
  >
30
- Save and new
31
- </AntButton>
35
+ <template #default>Save and new</template>
36
+
37
+ <template #invalidPermissionTooltipContent>
38
+ You have no permission to save this entry.<br>
39
+ Please contact your administrator.
40
+ </template>
41
+ </AntActionButton>
32
42
  </template>
@@ -2,20 +2,25 @@
2
2
  import {Grouped} from '../../enums/Grouped.enum';
3
3
  import {Size} from '../../enums/Size.enum';
4
4
  import {ColorType} from '../../enums/ColorType.enum';
5
- import AntButton from './AntButton.vue';
5
+ import AntActionButton from './AntActionButton.vue';
6
+ import {Position} from '../../enums';
6
7
 
7
8
  defineEmits(['click', 'blur']);
8
- defineProps<{
9
- size?: Size;
10
- disabled?: boolean;
11
- grouped?: Grouped;
12
- skeleton?: boolean;
13
- expanded?: boolean;
14
- }>()
9
+ withDefaults(defineProps<{
10
+ size?: Size;
11
+ disabled?: boolean;
12
+ grouped?: Grouped;
13
+ skeleton?: boolean;
14
+ expanded?: boolean;
15
+ canSave?: boolean;
16
+ invalidPermissionTooltipPosition?: Position;
17
+ }>(), {
18
+ canSave: true
19
+ });
15
20
  </script>
16
21
 
17
22
  <template>
18
- <AntButton
23
+ <AntActionButton
19
24
  :size="size"
20
25
  :disabled="disabled"
21
26
  :grouped="grouped"
@@ -23,9 +28,16 @@ defineProps<{
23
28
  :expanded="expanded"
24
29
  :color-type="ColorType.primary"
25
30
  data-e2e="save-button"
31
+ :has-permission="canSave"
32
+ :invalid-permission-tooltip-position="invalidPermissionTooltipPosition"
26
33
  @click="$emit('click')"
27
34
  @blur="$emit('blur')"
28
35
  >
29
- Save
30
- </AntButton>
36
+ <template #default>Save</template>
37
+
38
+ <template #invalidPermissionTooltipContent>
39
+ You have no permission to save this entry.<br>
40
+ Please contact your administrator.
41
+ </template>
42
+ </AntActionButton>
31
43
  </template>
@@ -0,0 +1,11 @@
1
+ import AntActionButton from '../AntActionButton.vue';
2
+ import { type Meta, type StoryObj } from '@storybook/vue3';
3
+ declare const meta: Meta<typeof AntActionButton>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof AntActionButton>;
6
+ export declare const Docs: Story;
7
+ export declare const Disabled: Story;
8
+ export declare const Grouped: Story;
9
+ export declare const Skeleton: Story;
10
+ export declare const Expanded: Story;
11
+ export declare const WithPermissionTooltip: Story;
@@ -0,0 +1,79 @@
1
+ import AntActionButton from "../AntActionButton.vue";
2
+ import { Size } from "../../../enums/Size.enum.mjs";
3
+ import { Grouped as _Grouped } from "../../../enums/Grouped.enum.mjs";
4
+ import { Position } from "../../../enums/index.mjs";
5
+ const meta = {
6
+ title: "Components/Buttons/Action Button",
7
+ component: AntActionButton,
8
+ parameters: { controls: { sort: "requiredFirst" } },
9
+ argTypes: {
10
+ size: {
11
+ control: { type: "radio" },
12
+ options: Object.values(Size)
13
+ },
14
+ grouped: {
15
+ control: { type: "select" },
16
+ options: Object.values(_Grouped)
17
+ },
18
+ invalidPermissionTooltipPosition: {
19
+ control: { type: "select" },
20
+ options: Object.values(Position)
21
+ }
22
+ }
23
+ };
24
+ export default meta;
25
+ export const Docs = {
26
+ render: (args) => ({
27
+ components: { AntActionButton },
28
+ setup() {
29
+ return { args };
30
+ },
31
+ template: '<AntActionButton v-bind="args">Action Button</AntActionButton>'
32
+ }),
33
+ args: {}
34
+ };
35
+ export const Disabled = {
36
+ render: Docs.render,
37
+ args: {
38
+ ...Docs.args,
39
+ disabled: true
40
+ }
41
+ };
42
+ export const Grouped = {
43
+ render: Docs.render,
44
+ args: {
45
+ ...Docs.args,
46
+ grouped: _Grouped.left
47
+ }
48
+ };
49
+ export const Skeleton = {
50
+ render: Docs.render,
51
+ args: {
52
+ ...Docs.args,
53
+ skeleton: true
54
+ }
55
+ };
56
+ export const Expanded = {
57
+ render: Docs.render,
58
+ args: {
59
+ ...Docs.args,
60
+ expanded: true
61
+ }
62
+ };
63
+ export const WithPermissionTooltip = {
64
+ render: (args) => ({
65
+ components: { AntActionButton },
66
+ setup() {
67
+ return { args };
68
+ },
69
+ template: `<AntActionButton v-bind="args">
70
+ Action Button
71
+
72
+ <template #invalidPermissionTooltipContent>You have no permission to do this</template>
73
+ </AntActionButton>`
74
+ }),
75
+ args: {
76
+ hasPermission: false,
77
+ invalidPermissionTooltipPosition: Position.right
78
+ }
79
+ };
@@ -8,3 +8,4 @@ export declare const Disabled: Story;
8
8
  export declare const Grouped: Story;
9
9
  export declare const Skeleton: Story;
10
10
  export declare const Expanded: Story;
11
+ export declare const InvalidPermission: Story;