frappe-ui 0.1.143 → 0.1.145
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.
- package/frappe/Onboarding/IntermediateStepModal.vue +7 -1
- package/frappe/Onboarding/OnboardingSteps.vue +44 -10
- package/frappe/Onboarding/onboarding.js +27 -14
- package/frappe/session.js +8 -0
- package/package.json +1 -1
- package/src/components/Avatar.vue +1 -1
- package/src/components/Charts/eChartOptions.ts +4 -0
- package/src/components/DatePicker/DatePicker.vue +3 -2
- package/src/components/DatePicker/DateTimePicker.vue +3 -1
- package/vite/lucideIcons.js +1 -1
|
@@ -7,7 +7,13 @@
|
|
|
7
7
|
<slot>
|
|
8
8
|
<div class="flex flex-col gap-2 text-ink-gray-9 text-base">
|
|
9
9
|
<div v-if="currentStep.message">{{ currentStep.message }}</div>
|
|
10
|
-
<video
|
|
10
|
+
<video
|
|
11
|
+
v-if="currentStep.videoURL"
|
|
12
|
+
class="w-full rounded"
|
|
13
|
+
controls
|
|
14
|
+
autoplay
|
|
15
|
+
muted
|
|
16
|
+
>
|
|
11
17
|
<source :src="currentStep.videoURL" type="video/mp4" />
|
|
12
18
|
Your browser does not support the video tag.
|
|
13
19
|
</video>
|
|
@@ -35,25 +35,38 @@
|
|
|
35
35
|
v-for="step in steps"
|
|
36
36
|
:key="step.title"
|
|
37
37
|
class="group w-full flex gap-2 justify-between items-center hover:bg-surface-gray-1 rounded px-2 py-1.5 cursor-pointer"
|
|
38
|
-
@click.stop="
|
|
38
|
+
@click.stop="
|
|
39
|
+
() => !step.completed && !isDependent(step) && step.onClick()
|
|
40
|
+
"
|
|
39
41
|
>
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
:
|
|
42
|
+
<component
|
|
43
|
+
:is="isDependent(step) ? Tooltip : 'div'"
|
|
44
|
+
:text="dependsOnTooltip(step)"
|
|
43
45
|
>
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
<div
|
|
47
|
+
class="flex gap-2 items-center"
|
|
48
|
+
:class="[
|
|
49
|
+
step.completed
|
|
50
|
+
? 'text-ink-gray-5'
|
|
51
|
+
: isDependent(step)
|
|
52
|
+
? 'text-ink-gray-4'
|
|
53
|
+
: 'text-ink-gray-8',
|
|
54
|
+
]"
|
|
55
|
+
>
|
|
56
|
+
<component :is="step.icon" class="h-4" />
|
|
57
|
+
<div class="text-base" :class="{ 'line-through': step.completed }">
|
|
58
|
+
{{ step.title }}
|
|
59
|
+
</div>
|
|
47
60
|
</div>
|
|
48
|
-
</
|
|
61
|
+
</component>
|
|
49
62
|
<Button
|
|
50
|
-
v-if="!step.completed"
|
|
63
|
+
v-if="!step.completed && !isDependent(step)"
|
|
51
64
|
:label="'Skip'"
|
|
52
65
|
class="!h-4 text-xs !text-ink-gray-6 hidden group-hover:flex"
|
|
53
66
|
@click="() => skip(step.name, afterSkip)"
|
|
54
67
|
/>
|
|
55
68
|
<Button
|
|
56
|
-
v-else
|
|
69
|
+
v-else-if="!isDependent(step)"
|
|
57
70
|
:label="'Reset'"
|
|
58
71
|
class="!h-4 text-xs !text-ink-gray-6 hidden group-hover:flex"
|
|
59
72
|
@click.stop="() => reset(step.name, afterReset)"
|
|
@@ -64,6 +77,7 @@
|
|
|
64
77
|
</template>
|
|
65
78
|
<script setup>
|
|
66
79
|
import { useOnboarding } from './onboarding'
|
|
80
|
+
import Tooltip from '../../src/components/Tooltip/Tooltip.vue'
|
|
67
81
|
import Button from '../../src/components/Button/Button.vue'
|
|
68
82
|
import Badge from '../../src/components/Badge.vue'
|
|
69
83
|
|
|
@@ -98,6 +112,26 @@ const props = defineProps({
|
|
|
98
112
|
},
|
|
99
113
|
})
|
|
100
114
|
|
|
115
|
+
function isDependent(step) {
|
|
116
|
+
if (step.dependsOn && !step.completed) {
|
|
117
|
+
const dependsOnStep = steps.find((s) => s.name === step.dependsOn)
|
|
118
|
+
if (dependsOnStep && !dependsOnStep.completed) {
|
|
119
|
+
return true
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return false
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function dependsOnTooltip(step) {
|
|
126
|
+
if (step.dependsOn && !step.completed) {
|
|
127
|
+
const dependsOnStep = steps.find((s) => s.name === step.dependsOn)
|
|
128
|
+
if (dependsOnStep && !dependsOnStep.completed) {
|
|
129
|
+
return `You need to complete "${dependsOnStep.title}" first.`
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return ''
|
|
133
|
+
}
|
|
134
|
+
|
|
101
135
|
const {
|
|
102
136
|
steps,
|
|
103
137
|
stepsCompleted,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import call from '../../src/utils/call'
|
|
2
2
|
import { createResource } from '../../src/resources'
|
|
3
|
-
import { minimize } from '../Help/help'
|
|
3
|
+
import { minimize, showHelpModal } from '../Help/help'
|
|
4
|
+
import { sessionUser } from '../session'
|
|
4
5
|
import { useStorage } from '@vueuse/core'
|
|
5
6
|
import { computed, reactive } from 'vue'
|
|
6
7
|
|
|
@@ -8,13 +9,18 @@ const onboardings = reactive({})
|
|
|
8
9
|
const onboardingStatus = useStorage('onboardingStatus', {})
|
|
9
10
|
|
|
10
11
|
export function useOnboarding(appName) {
|
|
12
|
+
const user = sessionUser()
|
|
13
|
+
|
|
14
|
+
if (!user || user === 'Guest') return
|
|
15
|
+
|
|
11
16
|
const isOnboardingStepsCompleted = useStorage(
|
|
12
|
-
'isOnboardingStepsCompleted' + appName,
|
|
17
|
+
'isOnboardingStepsCompleted' + appName + user,
|
|
13
18
|
false,
|
|
14
19
|
)
|
|
15
20
|
|
|
16
21
|
const onboardingSteps = computed(
|
|
17
|
-
() =>
|
|
22
|
+
() =>
|
|
23
|
+
onboardingStatus.value?.[user]?.[appName + '_onboarding_status'] || [],
|
|
18
24
|
)
|
|
19
25
|
|
|
20
26
|
if (!onboardingSteps.value.length && !isOnboardingStepsCompleted.value) {
|
|
@@ -23,7 +29,7 @@ export function useOnboarding(appName) {
|
|
|
23
29
|
cache: 'onboarding_status',
|
|
24
30
|
auto: true,
|
|
25
31
|
onSuccess: (data) => {
|
|
26
|
-
onboardingStatus.value = data
|
|
32
|
+
onboardingStatus.value[user] = data
|
|
27
33
|
syncStatus()
|
|
28
34
|
},
|
|
29
35
|
})
|
|
@@ -63,11 +69,13 @@ export function useOnboarding(appName) {
|
|
|
63
69
|
if (isOnboardingStepsCompleted.value) return
|
|
64
70
|
|
|
65
71
|
if (!onboardingSteps.value.length) {
|
|
66
|
-
onboardingStatus.value[
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
if (!onboardingStatus.value[user]) {
|
|
73
|
+
onboardingStatus.value[user] = {}
|
|
74
|
+
}
|
|
75
|
+
onboardingStatus.value[user][appName + '_onboarding_status'] =
|
|
76
|
+
onboardings[appName].map((s) => {
|
|
77
|
+
return { name: s.name, completed: false }
|
|
78
|
+
})
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
let index = onboardingSteps.value.findIndex((s) => s.name === step)
|
|
@@ -87,11 +95,14 @@ export function useOnboarding(appName) {
|
|
|
87
95
|
if (isOnboardingStepsCompleted.value && value) return
|
|
88
96
|
|
|
89
97
|
if (!onboardingSteps.value.length) {
|
|
90
|
-
onboardingStatus.value[
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
98
|
+
if (!onboardingStatus.value[user]) {
|
|
99
|
+
onboardingStatus.value[user] = {}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
onboardingStatus.value[user][appName + '_onboarding_status'] =
|
|
103
|
+
onboardings[appName].map((s) => {
|
|
104
|
+
return { name: s.name, completed: value }
|
|
105
|
+
})
|
|
95
106
|
} else {
|
|
96
107
|
onboardingSteps.value.forEach((step) => {
|
|
97
108
|
step.completed = value
|
|
@@ -129,6 +140,8 @@ export function useOnboarding(appName) {
|
|
|
129
140
|
}
|
|
130
141
|
|
|
131
142
|
function setUp(steps) {
|
|
143
|
+
showHelpModal.value = !isOnboardingStepsCompleted.value
|
|
144
|
+
|
|
132
145
|
if (onboardings[appName]) return
|
|
133
146
|
|
|
134
147
|
onboardings[appName] = steps
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
/>
|
|
13
13
|
<div
|
|
14
14
|
v-else
|
|
15
|
-
class="flex h-full w-full items-center justify-center bg-surface-gray-2 uppercase text-ink-gray-5"
|
|
15
|
+
class="flex h-full w-full items-center justify-center bg-surface-gray-2 uppercase text-ink-gray-5 select-none"
|
|
16
16
|
:class="[labelClasses, shapeClasses]"
|
|
17
17
|
>
|
|
18
18
|
<div :class="iconClasses" v-if="$slots.default">
|
|
@@ -284,6 +284,8 @@ function getYAxisOptions(config: AxisChartConfig) {
|
|
|
284
284
|
return formatValue(value, 1, true)
|
|
285
285
|
},
|
|
286
286
|
},
|
|
287
|
+
min: config.yAxis.yMin,
|
|
288
|
+
max: config.yAxis.yMax,
|
|
287
289
|
}
|
|
288
290
|
|
|
289
291
|
const secondaryYAxisOptions = {
|
|
@@ -324,6 +326,8 @@ function getYAxisOptions(config: AxisChartConfig) {
|
|
|
324
326
|
},
|
|
325
327
|
// color: '#000',
|
|
326
328
|
},
|
|
329
|
+
min: config.y2Axis?.yMin,
|
|
330
|
+
max: config.y2Axis?.yMax,
|
|
327
331
|
}
|
|
328
332
|
|
|
329
333
|
return config.swapXY
|
|
@@ -8,14 +8,15 @@
|
|
|
8
8
|
<TextInput
|
|
9
9
|
readonly
|
|
10
10
|
type="text"
|
|
11
|
-
icon-left="calendar"
|
|
12
11
|
:placeholder="placeholder"
|
|
13
12
|
:value="dateValue && formatter ? formatter(dateValue) : dateValue"
|
|
14
13
|
@focus="!readonly ? togglePopover() : null"
|
|
15
14
|
class="w-full"
|
|
16
15
|
:class="inputClass"
|
|
17
16
|
v-bind="$attrs"
|
|
18
|
-
|
|
17
|
+
>
|
|
18
|
+
<template #prefix><LucideCalendar class="size-4" /></template>
|
|
19
|
+
</TextInput>
|
|
19
20
|
</template>
|
|
20
21
|
|
|
21
22
|
<template #body="{ togglePopover }">
|
package/vite/lucideIcons.js
CHANGED
|
@@ -30,7 +30,7 @@ function getIcons() {
|
|
|
30
30
|
let iconSvg = LucideIcons[icon]
|
|
31
31
|
|
|
32
32
|
// set stroke-width to 1.5
|
|
33
|
-
if (iconSvg && iconSvg.includes('stroke-width')) {
|
|
33
|
+
if (typeof iconSvg === 'string' && iconSvg.includes('stroke-width')) {
|
|
34
34
|
iconSvg = iconSvg.replace(/stroke-width="2"/g, 'stroke-width="1.5"')
|
|
35
35
|
}
|
|
36
36
|
icons[icon] = iconSvg
|