pgo-ui 1.1.47 → 1.1.49

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgo-ui",
3
- "version": "1.1.47",
3
+ "version": "1.1.49",
4
4
  "description": "A Vue 3 component library with PGO design system",
5
5
  "private": false,
6
6
  "type": "module",
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <div class="space-y-4">
3
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
4
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
5
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Default</p>
6
+ <BarChart
7
+ :series="[
8
+ { name: 'Revenue', data: [30, 40, 35, 50, 49, 60] },
9
+ { name: 'Expenses', data: [20, 30, 25, 40, 30, 45] }
10
+ ]"
11
+ :categories="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']"
12
+ :height="280"
13
+ />
14
+ </div>
15
+
16
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
17
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Stacked + Data Labels</p>
18
+ <BarChart
19
+ :series="[
20
+ { name: 'Online', data: [44, 55, 41, 67, 22, 43] },
21
+ { name: 'In-Store', data: [13, 23, 20, 8, 13, 27] }
22
+ ]"
23
+ :categories="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']"
24
+ :colors="['#8B5CF6', '#F59E0B']"
25
+ :stacked="true"
26
+ :show-data-labels="true"
27
+ :height="280"
28
+ />
29
+ </div>
30
+ </div>
31
+
32
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
33
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
34
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Horizontal + Bilingual Labels</p>
35
+ <BarChart
36
+ :series="[
37
+ { name: { en: 'Letters', dv: 'ސިޓީ' }, data: [40, 55, 70, 48, 90] },
38
+ { name: { en: 'Cases', dv: 'މައްސަލަ' }, data: [20, 35, 25, 50, 45] }
39
+ ]"
40
+ :categories="['Dept A', 'Dept B', 'Dept C', 'Dept D', 'Dept E']"
41
+ :colors="['#3B82F6', '#10B981']"
42
+ :horizontal="true"
43
+ :height="280"
44
+ />
45
+ </div>
46
+
47
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
48
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Custom Colors + No Legend</p>
49
+ <BarChart
50
+ :series="[
51
+ { name: 'Temperature', data: [28, 30, 32, 31, 33, 35, 34] }
52
+ ]"
53
+ :categories="['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']"
54
+ :colors="['#EF4444']"
55
+ :show-legend="false"
56
+ column-width="40%"
57
+ :height="200"
58
+ />
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </template>
63
+
64
+ <script setup>
65
+ import { BarChart } from '../pgo'
66
+ </script>
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <div class="space-y-4">
3
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
4
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
5
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Default</p>
6
+ <BubbleChart
7
+ :series="[
8
+ { name: 'Product A', data: [[10, 20, 15], [20, 30, 25], [30, 15, 35], [40, 45, 20], [50, 35, 30]] },
9
+ { name: 'Product B', data: [[15, 25, 20], [25, 40, 15], [35, 20, 40], [45, 50, 25], [55, 30, 35]] }
10
+ ]"
11
+ :height="280"
12
+ />
13
+ </div>
14
+
15
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
16
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Axis Titles + Data Labels</p>
17
+ <BubbleChart
18
+ :series="[
19
+ { name: { en: 'Revenue', dv: 'އާމްދަނީ' }, data: [[5, 50, 20], [15, 80, 30], [25, 60, 45], [35, 90, 25], [45, 70, 35]] }
20
+ ]"
21
+ :xaxis-title="{ en: 'Months', dv: 'މަސް' }"
22
+ :yaxis-title="{ en: 'Amount', dv: 'ޢަދަދު' }"
23
+ :colors="['#8B5CF6']"
24
+ :show-data-labels="true"
25
+ :height="280"
26
+ />
27
+ </div>
28
+ </div>
29
+
30
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
31
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
32
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Custom Bubble Sizes</p>
33
+ <BubbleChart
34
+ :series="[
35
+ { name: 'Group 1', data: [[10, 30, 10], [20, 50, 30], [30, 40, 50], [40, 60, 20]] },
36
+ { name: 'Group 2', data: [[12, 35, 25], [22, 55, 15], [32, 45, 40], [42, 65, 35]] }
37
+ ]"
38
+ :colors="['#10B981', '#F59E0B']"
39
+ :min-bubble-size="5"
40
+ :max-bubble-size="70"
41
+ :height="280"
42
+ />
43
+ </div>
44
+
45
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
46
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Single Series + No Legend</p>
47
+ <BubbleChart
48
+ :series="[
49
+ { name: 'Data', data: [[8, 20, 30], [18, 40, 15], [28, 25, 45], [38, 55, 20], [48, 35, 40], [58, 45, 25]] }
50
+ ]"
51
+ :colors="['#EF4444']"
52
+ :show-legend="false"
53
+ :height="200"
54
+ />
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </template>
59
+
60
+ <script setup>
61
+ import { BubbleChart } from '../pgo'
62
+ </script>
@@ -0,0 +1,83 @@
1
+ <template>
2
+ <div class="space-y-4">
3
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
4
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
5
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Default</p>
6
+ <TreemapChart
7
+ :series="[
8
+ { data: [
9
+ { x: 'Criminal', y: 120 },
10
+ { x: 'Civil', y: 85 },
11
+ { x: 'Family', y: 60 },
12
+ { x: 'Commercial', y: 45 },
13
+ { x: 'Administrative', y: 30 },
14
+ { x: 'Other', y: 20 }
15
+ ]}
16
+ ]"
17
+ :height="280"
18
+ />
19
+ </div>
20
+
21
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
22
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Bilingual Labels</p>
23
+ <TreemapChart
24
+ :series="[
25
+ { data: [
26
+ { x: { en: 'Letters', dv: 'ސިޓީ' }, y: 90 },
27
+ { x: { en: 'Cases', dv: 'މައްސަލަ' }, y: 75 },
28
+ { x: { en: 'Reports', dv: 'ރިޕޯޓް' }, y: 50 },
29
+ { x: { en: 'Complaints', dv: 'ޝަކުވާ' }, y: 35 }
30
+ ]}
31
+ ]"
32
+ :colors="['#8B5CF6', '#EC4899', '#14B8A6', '#F97316']"
33
+ :height="280"
34
+ />
35
+ </div>
36
+ </div>
37
+
38
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
39
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
40
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Multi-group</p>
41
+ <TreemapChart
42
+ :series="[
43
+ { name: 'Dept A', data: [
44
+ { x: 'Criminal', y: 40 },
45
+ { x: 'Civil', y: 30 },
46
+ { x: 'Family', y: 20 }
47
+ ]},
48
+ { name: 'Dept B', data: [
49
+ { x: 'Criminal', y: 55 },
50
+ { x: 'Civil', y: 25 },
51
+ { x: 'Family', y: 35 }
52
+ ]}
53
+ ]"
54
+ :distributed="false"
55
+ :colors="['#3B82F6', '#10B981']"
56
+ :height="280"
57
+ />
58
+ </div>
59
+
60
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
61
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">No Data Labels + Custom Colors</p>
62
+ <TreemapChart
63
+ :series="[
64
+ { data: [
65
+ { x: 'A', y: 100 },
66
+ { x: 'B', y: 80 },
67
+ { x: 'C', y: 60 },
68
+ { x: 'D', y: 40 },
69
+ { x: 'E', y: 20 }
70
+ ]}
71
+ ]"
72
+ :colors="['#EF4444', '#F59E0B', '#10B981', '#3B82F6', '#8B5CF6']"
73
+ :show-data-labels="false"
74
+ :height="200"
75
+ />
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </template>
80
+
81
+ <script setup>
82
+ import { TreemapChart } from '../pgo'
83
+ </script>
@@ -0,0 +1,137 @@
1
+ <template>
2
+ <VueApexCharts
3
+ v-if="ready"
4
+ type="bar"
5
+ :options="chartOptions"
6
+ :series="chartSeries"
7
+ :height="height"
8
+ />
9
+ </template>
10
+
11
+ <script setup>
12
+ import { computed, inject, ref, onMounted } from 'vue'
13
+ import VueApexCharts from 'vue3-apexcharts'
14
+
15
+ const ready = ref(false)
16
+
17
+ onMounted(() => {
18
+ requestAnimationFrame(() => {
19
+ ready.value = true
20
+ })
21
+ })
22
+
23
+ const i18n = inject('i18n', null)
24
+
25
+ const defaultColors = ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#14B8A6', '#F97316']
26
+
27
+ const props = defineProps({
28
+ series: {
29
+ type: Array,
30
+ required: true
31
+ },
32
+ categories: {
33
+ type: Array,
34
+ default: () => []
35
+ },
36
+ colors: {
37
+ type: Array,
38
+ default: () => []
39
+ },
40
+ height: {
41
+ type: [String, Number],
42
+ default: 350
43
+ },
44
+ showLegend: {
45
+ type: Boolean,
46
+ default: true
47
+ },
48
+ showDataLabels: {
49
+ type: Boolean,
50
+ default: false
51
+ },
52
+ horizontal: {
53
+ type: Boolean,
54
+ default: false
55
+ },
56
+ stacked: {
57
+ type: Boolean,
58
+ default: false
59
+ },
60
+ columnWidth: {
61
+ type: String,
62
+ default: '55%'
63
+ },
64
+ lang: {
65
+ type: String,
66
+ default: ''
67
+ }
68
+ })
69
+
70
+ const currentLang = computed(() => props.lang || i18n?.language?.value || 'dv')
71
+
72
+ const resolveLabel = (label) => {
73
+ if (!label) return ''
74
+ if (typeof label === 'string') return label
75
+ if (typeof label === 'object') return label[currentLang.value] ?? label['en'] ?? ''
76
+ return ''
77
+ }
78
+
79
+ const paletteColors = computed(() =>
80
+ props.colors.length ? props.colors : defaultColors.slice(0, props.series.length)
81
+ )
82
+
83
+ const chartSeries = computed(() =>
84
+ props.series.map(s => ({
85
+ name: resolveLabel(s.name),
86
+ data: s.data
87
+ }))
88
+ )
89
+
90
+ const chartOptions = computed(() => ({
91
+ chart: {
92
+ type: 'bar',
93
+ stacked: props.stacked,
94
+ fontFamily: currentLang.value === 'dv' ? 'Faruma, sans-serif' : 'inherit',
95
+ toolbar: { show: false }
96
+ },
97
+ colors: paletteColors.value,
98
+ plotOptions: {
99
+ bar: {
100
+ horizontal: props.horizontal,
101
+ columnWidth: props.columnWidth,
102
+ borderRadius: 4
103
+ }
104
+ },
105
+ stroke: {
106
+ show: true,
107
+ width: 2,
108
+ colors: ['transparent']
109
+ },
110
+ xaxis: {
111
+ categories: props.categories
112
+ },
113
+ legend: {
114
+ show: props.showLegend,
115
+ position: 'bottom',
116
+ fontSize: '13px',
117
+ fontFamily: currentLang.value === 'dv' ? 'Faruma, sans-serif' : 'inherit'
118
+ },
119
+ dataLabels: {
120
+ enabled: props.showDataLabels
121
+ },
122
+ tooltip: {
123
+ y: {
124
+ formatter: (val) => `${val}`
125
+ }
126
+ },
127
+ responsive: [
128
+ {
129
+ breakpoint: 480,
130
+ options: {
131
+ chart: { width: 300 },
132
+ legend: { position: 'bottom' }
133
+ }
134
+ }
135
+ ]
136
+ }))
137
+ </script>
@@ -0,0 +1,146 @@
1
+ <template>
2
+ <VueApexCharts
3
+ v-if="ready"
4
+ type="bubble"
5
+ :options="chartOptions"
6
+ :series="chartSeries"
7
+ :height="height"
8
+ />
9
+ </template>
10
+
11
+ <script setup>
12
+ import { computed, inject, ref, onMounted } from 'vue'
13
+ import VueApexCharts from 'vue3-apexcharts'
14
+
15
+ const ready = ref(false)
16
+
17
+ onMounted(() => {
18
+ requestAnimationFrame(() => {
19
+ ready.value = true
20
+ })
21
+ })
22
+
23
+ const i18n = inject('i18n', null)
24
+
25
+ const defaultColors = ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#14B8A6', '#F97316']
26
+
27
+ const props = defineProps({
28
+ series: {
29
+ type: Array,
30
+ required: true
31
+ },
32
+ colors: {
33
+ type: Array,
34
+ default: () => []
35
+ },
36
+ height: {
37
+ type: [String, Number],
38
+ default: 350
39
+ },
40
+ showLegend: {
41
+ type: Boolean,
42
+ default: true
43
+ },
44
+ showDataLabels: {
45
+ type: Boolean,
46
+ default: false
47
+ },
48
+ xaxisTitle: {
49
+ type: [String, Object],
50
+ default: ''
51
+ },
52
+ yaxisTitle: {
53
+ type: [String, Object],
54
+ default: ''
55
+ },
56
+ minBubbleSize: {
57
+ type: Number,
58
+ default: 10
59
+ },
60
+ maxBubbleSize: {
61
+ type: Number,
62
+ default: 50
63
+ },
64
+ lang: {
65
+ type: String,
66
+ default: ''
67
+ }
68
+ })
69
+
70
+ const currentLang = computed(() => props.lang || i18n?.language?.value || 'dv')
71
+
72
+ const resolveLabel = (label) => {
73
+ if (!label) return ''
74
+ if (typeof label === 'string') return label
75
+ if (typeof label === 'object') return label[currentLang.value] ?? label['en'] ?? ''
76
+ return ''
77
+ }
78
+
79
+ const paletteColors = computed(() =>
80
+ props.colors.length ? props.colors : defaultColors.slice(0, props.series.length)
81
+ )
82
+
83
+ const chartSeries = computed(() =>
84
+ props.series.map(s => ({
85
+ name: resolveLabel(s.name),
86
+ data: s.data
87
+ }))
88
+ )
89
+
90
+ const chartOptions = computed(() => ({
91
+ chart: {
92
+ type: 'bubble',
93
+ fontFamily: currentLang.value === 'dv' ? 'Faruma, sans-serif' : 'inherit',
94
+ toolbar: { show: false }
95
+ },
96
+ colors: paletteColors.value,
97
+ fill: {
98
+ opacity: 0.8
99
+ },
100
+ plotOptions: {
101
+ bubble: {
102
+ minBubbleRadius: props.minBubbleSize,
103
+ maxBubbleRadius: props.maxBubbleSize
104
+ }
105
+ },
106
+ xaxis: {
107
+ title: {
108
+ text: resolveLabel(props.xaxisTitle),
109
+ style: {
110
+ fontFamily: currentLang.value === 'dv' ? 'Faruma, sans-serif' : 'inherit'
111
+ }
112
+ }
113
+ },
114
+ yaxis: {
115
+ title: {
116
+ text: resolveLabel(props.yaxisTitle),
117
+ style: {
118
+ fontFamily: currentLang.value === 'dv' ? 'Faruma, sans-serif' : 'inherit'
119
+ }
120
+ }
121
+ },
122
+ legend: {
123
+ show: props.showLegend,
124
+ position: 'bottom',
125
+ fontSize: '13px',
126
+ fontFamily: currentLang.value === 'dv' ? 'Faruma, sans-serif' : 'inherit'
127
+ },
128
+ dataLabels: {
129
+ enabled: props.showDataLabels
130
+ },
131
+ tooltip: {
132
+ y: {
133
+ formatter: (val) => `${val}`
134
+ }
135
+ },
136
+ responsive: [
137
+ {
138
+ breakpoint: 480,
139
+ options: {
140
+ chart: { width: 300 },
141
+ legend: { position: 'bottom' }
142
+ }
143
+ }
144
+ ]
145
+ }))
146
+ </script>
@@ -0,0 +1,116 @@
1
+ <template>
2
+ <VueApexCharts
3
+ v-if="ready"
4
+ type="treemap"
5
+ :options="chartOptions"
6
+ :series="chartSeries"
7
+ :height="height"
8
+ />
9
+ </template>
10
+
11
+ <script setup>
12
+ import { computed, inject, ref, onMounted } from 'vue'
13
+ import VueApexCharts from 'vue3-apexcharts'
14
+
15
+ const ready = ref(false)
16
+
17
+ onMounted(() => {
18
+ requestAnimationFrame(() => {
19
+ ready.value = true
20
+ })
21
+ })
22
+
23
+ const i18n = inject('i18n', null)
24
+
25
+ const defaultColors = ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#14B8A6', '#F97316']
26
+
27
+ const props = defineProps({
28
+ series: {
29
+ type: Array,
30
+ required: true
31
+ },
32
+ colors: {
33
+ type: Array,
34
+ default: () => []
35
+ },
36
+ height: {
37
+ type: [String, Number],
38
+ default: 350
39
+ },
40
+ showDataLabels: {
41
+ type: Boolean,
42
+ default: true
43
+ },
44
+ distributed: {
45
+ type: Boolean,
46
+ default: true
47
+ },
48
+ enableShadeIntensity: {
49
+ type: Boolean,
50
+ default: true
51
+ },
52
+ lang: {
53
+ type: String,
54
+ default: ''
55
+ }
56
+ })
57
+
58
+ const currentLang = computed(() => props.lang || i18n?.language?.value || 'dv')
59
+
60
+ const resolveLabel = (label) => {
61
+ if (!label) return ''
62
+ if (typeof label === 'string') return label
63
+ if (typeof label === 'object') return label[currentLang.value] ?? label['en'] ?? ''
64
+ return ''
65
+ }
66
+
67
+ const paletteColors = computed(() =>
68
+ props.colors.length ? props.colors : defaultColors
69
+ )
70
+
71
+ const chartSeries = computed(() =>
72
+ props.series.map(s => ({
73
+ name: resolveLabel(s.name),
74
+ data: s.data.map(d => ({
75
+ x: resolveLabel(d.x),
76
+ y: d.y
77
+ }))
78
+ }))
79
+ )
80
+
81
+ const chartOptions = computed(() => ({
82
+ chart: {
83
+ type: 'treemap',
84
+ fontFamily: currentLang.value === 'dv' ? 'Faruma, sans-serif' : 'inherit',
85
+ toolbar: { show: false }
86
+ },
87
+ colors: paletteColors.value,
88
+ plotOptions: {
89
+ treemap: {
90
+ distributed: props.distributed,
91
+ enableShades: props.enableShadeIntensity,
92
+ shadeIntensity: 0.5
93
+ }
94
+ },
95
+ dataLabels: {
96
+ enabled: props.showDataLabels,
97
+ style: {
98
+ fontSize: '13px',
99
+ fontFamily: currentLang.value === 'dv' ? 'Faruma, sans-serif' : 'inherit'
100
+ }
101
+ },
102
+ tooltip: {
103
+ y: {
104
+ formatter: (val) => `${val}`
105
+ }
106
+ },
107
+ responsive: [
108
+ {
109
+ breakpoint: 480,
110
+ options: {
111
+ chart: { width: 300 }
112
+ }
113
+ }
114
+ ]
115
+ }))
116
+ </script>
@@ -154,6 +154,7 @@
154
154
  const clickedButton = ref('');
155
155
  const isPreFilled = ref(false)
156
156
  const originalFormData = ref({})
157
+ const dataChanged = ref(false)
157
158
 
158
159
  const emit = defineEmits([
159
160
  'update:modelValue',
@@ -1011,12 +1012,14 @@
1011
1012
  isPreFilled.value = false
1012
1013
  originalFormData.value = {}
1013
1014
  valid.value = false;
1014
- formMode.value = props.mode
1015
+ formMode.value = props.mode
1015
1016
  formId.value = null
1016
- emit('close', false);
1017
+ emit('close', dataChanged.value);
1018
+ dataChanged.value = false;
1017
1019
  };
1018
1020
 
1019
1021
  const handleUploadSuccess = () => {
1022
+ dataChanged.value = true;
1020
1023
  fetchData();
1021
1024
  };
1022
1025
  // Initialize on mount
@@ -52,6 +52,9 @@ import ToastItem from './Deprecated/ToastItem.vue'
52
52
  import SearchBox from './SearchBox.vue'
53
53
  import DonutChart from './charts/DonutChart.vue'
54
54
  import LineChart from './charts/LineChart.vue'
55
+ import BarChart from './charts/BarChart.vue'
56
+ import BubbleChart from './charts/BubbleChart.vue'
57
+ import TreemapChart from './charts/TreemapChart.vue'
55
58
 
56
59
 
57
60
  // export { Chip, ChipGroup, DataTable, Dropdown, FileUpload, Form }
@@ -104,5 +107,8 @@ export { Button, Card, CardView, HeroIcon,
104
107
  Toolbar,
105
108
  Tooltip,
106
109
  DonutChart,
107
- LineChart
110
+ LineChart,
111
+ BarChart,
112
+ BubbleChart,
113
+ TreemapChart
108
114
  }