zrobienie jednego komponentu od wykresów. Naprawienie folderu public (favicon). Praca nad wykresami i statystykami.
This commit is contained in:
@@ -420,6 +420,8 @@
|
||||
"useDataStore": true,
|
||||
"chartsAndStatsStore": true,
|
||||
"useChartsAndStatsStore": true,
|
||||
"useCacheStore": true
|
||||
"useCacheStore": true,
|
||||
"cacheFullListResponses": true,
|
||||
"Switch": true
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB |
@@ -1,3 +0,0 @@
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<template></template>
|
||||
27
src/components/charts-and-stats/chartComponent.vue
Normal file
27
src/components/charts-and-stats/chartComponent.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<script lang="ts" setup>
|
||||
import type { ChartData, Config } from '@/types/chartsTypes';
|
||||
|
||||
defineProps<{
|
||||
config: Config;
|
||||
labels: string[];
|
||||
charts: Record<string, ChartData[]>;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-for="(chart, _, index) in charts" :key="index" class="flex flex-col">
|
||||
<!-- TODO: Zrobić własny tooltip -->
|
||||
|
||||
<Label class="my-4 text-center text-5xl font-bold text-primary"> {{ labels[index] }} </Label>
|
||||
|
||||
<LineChart
|
||||
:categories="config.categories"
|
||||
index="turn"
|
||||
:colors="config.colors"
|
||||
:data="chart"
|
||||
class="h-[500px]"
|
||||
:show-legend="true"
|
||||
:show-tooltip="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,3 +0,0 @@
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<template></template>
|
||||
@@ -1,3 +0,0 @@
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<template></template>
|
||||
@@ -1,3 +0,0 @@
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<template></template>
|
||||
@@ -1,3 +0,0 @@
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<template></template>
|
||||
@@ -1,115 +0,0 @@
|
||||
<script setup lang="ts" generic="T extends Record<string, any>">
|
||||
import type { BulletLegendItemInterface } from '@unovis/ts'
|
||||
import type { BaseChartProps } from '.'
|
||||
import { ChartCrosshair, ChartLegend, defaultColors } from '@/components/ui/chart'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Axis, GroupedBar, StackedBar } from '@unovis/ts'
|
||||
import { VisAxis, VisGroupedBar, VisStackedBar, VisXYContainer } from '@unovis/vue'
|
||||
import { useMounted } from '@vueuse/core'
|
||||
import { type Component, computed, ref } from 'vue'
|
||||
|
||||
const props = withDefaults(defineProps<BaseChartProps<T> & {
|
||||
/**
|
||||
* Render custom tooltip component.
|
||||
*/
|
||||
customTooltip?: Component
|
||||
/**
|
||||
* Change the type of the chart
|
||||
* @default "grouped"
|
||||
*/
|
||||
type?: 'stacked' | 'grouped'
|
||||
/**
|
||||
* Rounded bar corners
|
||||
* @default 0
|
||||
*/
|
||||
roundedCorners?: number
|
||||
}>(), {
|
||||
type: 'grouped',
|
||||
margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),
|
||||
filterOpacity: 0.2,
|
||||
roundedCorners: 0,
|
||||
showXAxis: true,
|
||||
showYAxis: true,
|
||||
showTooltip: true,
|
||||
showLegend: true,
|
||||
showGridLine: true,
|
||||
})
|
||||
const emits = defineEmits<{
|
||||
legendItemClick: [d: BulletLegendItemInterface, i: number]
|
||||
}>()
|
||||
|
||||
type KeyOfT = Extract<keyof T, string>
|
||||
type Data = typeof props.data[number]
|
||||
|
||||
const index = computed(() => props.index as KeyOfT)
|
||||
const colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))
|
||||
const legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({
|
||||
name: category,
|
||||
color: colors.value[i],
|
||||
inactive: false,
|
||||
})))
|
||||
|
||||
const isMounted = useMounted()
|
||||
|
||||
function handleLegendItemClick(d: BulletLegendItemInterface, i: number) {
|
||||
emits('legendItemClick', d, i)
|
||||
}
|
||||
|
||||
const VisBarComponent = computed(() => props.type === 'grouped' ? VisGroupedBar : VisStackedBar)
|
||||
const selectorsBar = computed(() => props.type === 'grouped' ? GroupedBar.selectors.bar : StackedBar.selectors.bar)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')">
|
||||
<ChartLegend v-if="showLegend" v-model:items="legendItems" @legend-item-click="handleLegendItemClick" />
|
||||
|
||||
<VisXYContainer
|
||||
:data="data"
|
||||
:style="{ height: isMounted ? '100%' : 'auto' }"
|
||||
:margin="margin"
|
||||
>
|
||||
<ChartCrosshair v-if="showTooltip" :colors="colors" :items="legendItems" :custom-tooltip="customTooltip" :index="index" />
|
||||
|
||||
<VisBarComponent
|
||||
:x="(d: Data, i: number) => i"
|
||||
:y="categories.map(category => (d: Data) => d[category]) "
|
||||
:color="colors"
|
||||
:rounded-corners="roundedCorners"
|
||||
:bar-padding="0.05"
|
||||
:attributes="{
|
||||
[selectorsBar]: {
|
||||
opacity: (d: Data, i:number) => {
|
||||
const pos = i % categories.length
|
||||
return legendItems[pos]?.inactive ? filterOpacity : 1
|
||||
},
|
||||
},
|
||||
}"
|
||||
/>
|
||||
|
||||
<VisAxis
|
||||
v-if="showXAxis"
|
||||
type="x"
|
||||
:tick-format="xFormatter ?? ((v: number) => data[v]?.[index])"
|
||||
:grid-line="false"
|
||||
:tick-line="false"
|
||||
tick-text-color="hsl(var(--vis-text-color))"
|
||||
/>
|
||||
<VisAxis
|
||||
v-if="showYAxis"
|
||||
type="y"
|
||||
:tick-line="false"
|
||||
:tick-format="yFormatter"
|
||||
:domain-line="false"
|
||||
:grid-line="showGridLine"
|
||||
:attributes="{
|
||||
[Axis.selectors.grid]: {
|
||||
class: 'text-muted',
|
||||
},
|
||||
}"
|
||||
tick-text-color="hsl(var(--vis-text-color))"
|
||||
/>
|
||||
|
||||
<slot />
|
||||
</VisXYContainer>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,66 +0,0 @@
|
||||
export { default as BarChart } from './BarChart.vue'
|
||||
|
||||
import type { Spacing } from '@unovis/ts'
|
||||
|
||||
type KeyOf<T extends Record<string, any>> = Extract<keyof T, string>
|
||||
|
||||
export interface BaseChartProps<T extends Record<string, any>> {
|
||||
/**
|
||||
* The source data, in which each entry is a dictionary.
|
||||
*/
|
||||
data: T[]
|
||||
/**
|
||||
* Select the categories from your data. Used to populate the legend and toolip.
|
||||
*/
|
||||
categories: KeyOf<T>[]
|
||||
/**
|
||||
* Sets the key to map the data to the axis.
|
||||
*/
|
||||
index: KeyOf<T>
|
||||
/**
|
||||
* Change the default colors.
|
||||
*/
|
||||
colors?: string[]
|
||||
/**
|
||||
* Margin of each the container
|
||||
*/
|
||||
margin?: Spacing
|
||||
/**
|
||||
* Change the opacity of the non-selected field
|
||||
* @default 0.2
|
||||
*/
|
||||
filterOpacity?: number
|
||||
/**
|
||||
* Function to format X label
|
||||
*/
|
||||
xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string
|
||||
/**
|
||||
* Function to format Y label
|
||||
*/
|
||||
yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string
|
||||
/**
|
||||
* Controls the visibility of the X axis.
|
||||
* @default true
|
||||
*/
|
||||
showXAxis?: boolean
|
||||
/**
|
||||
* Controls the visibility of the Y axis.
|
||||
* @default true
|
||||
*/
|
||||
showYAxis?: boolean
|
||||
/**
|
||||
* Controls the visibility of tooltip.
|
||||
* @default true
|
||||
*/
|
||||
showTooltip?: boolean
|
||||
/**
|
||||
* Controls the visibility of legend.
|
||||
* @default true
|
||||
*/
|
||||
showLegend?: boolean
|
||||
/**
|
||||
* Controls the visibility of gridline.
|
||||
* @default true
|
||||
*/
|
||||
showGridLine?: boolean
|
||||
}
|
||||
@@ -1,105 +1,125 @@
|
||||
<script setup lang="ts" generic="T extends Record<string, any>">
|
||||
import type { BaseChartProps } from '.'
|
||||
import { ChartCrosshair, ChartLegend, defaultColors } from '@/components/ui/chart'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { type BulletLegendItemInterface, CurveType } from '@unovis/ts'
|
||||
import { Axis, Line } from '@unovis/ts'
|
||||
import { VisAxis, VisLine, VisXYContainer } from '@unovis/vue'
|
||||
import { useMounted } from '@vueuse/core'
|
||||
import { type Component, computed, ref } from 'vue'
|
||||
import { ChartCrosshair, ChartLegend, defaultColors } from '@/components/ui/chart';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Axis, type BulletLegendItemInterface, CurveType, Line } from '@unovis/ts';
|
||||
import { VisAxis, VisLine, VisXYContainer } from '@unovis/vue';
|
||||
import { useMounted } from '@vueuse/core';
|
||||
import { type Component, computed, ref } from 'vue';
|
||||
import type { BaseChartProps } from '.';
|
||||
|
||||
const props = withDefaults(defineProps<BaseChartProps<T> & {
|
||||
/**
|
||||
* Render custom tooltip component.
|
||||
*/
|
||||
customTooltip?: Component
|
||||
/**
|
||||
* Type of curve
|
||||
*/
|
||||
curveType?: CurveType
|
||||
}>(), {
|
||||
curveType: CurveType.MonotoneX,
|
||||
filterOpacity: 0.2,
|
||||
margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),
|
||||
showXAxis: true,
|
||||
showYAxis: true,
|
||||
showTooltip: true,
|
||||
showLegend: true,
|
||||
showGridLine: true,
|
||||
})
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
BaseChartProps<T> & {
|
||||
/**
|
||||
* Render custom tooltip component.
|
||||
*/
|
||||
customTooltip?: Component;
|
||||
/**
|
||||
* Type of curve
|
||||
*/
|
||||
curveType?: CurveType;
|
||||
}
|
||||
>(),
|
||||
{
|
||||
curveType: CurveType.MonotoneX,
|
||||
filterOpacity: 0.2,
|
||||
margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),
|
||||
showXAxis: true,
|
||||
showYAxis: true,
|
||||
showTooltip: true,
|
||||
showLegend: true,
|
||||
showGridLine: true
|
||||
}
|
||||
);
|
||||
|
||||
const emits = defineEmits<{
|
||||
legendItemClick: [d: BulletLegendItemInterface, i: number]
|
||||
}>()
|
||||
legendItemClick: [d: BulletLegendItemInterface, i: number];
|
||||
}>();
|
||||
|
||||
type KeyOfT = Extract<keyof T, string>
|
||||
type Data = typeof props.data[number]
|
||||
type KeyOfT = Extract<keyof T, string>;
|
||||
type Data = (typeof props.data)[number];
|
||||
|
||||
const index = computed(() => props.index as KeyOfT)
|
||||
const colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))
|
||||
const index = computed(() => props.index as KeyOfT);
|
||||
const colors = computed(() =>
|
||||
props.colors?.length ? props.colors : defaultColors(props.categories.length)
|
||||
);
|
||||
|
||||
const legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({
|
||||
name: category,
|
||||
color: colors.value[i],
|
||||
inactive: false,
|
||||
})))
|
||||
const legendItems = ref<BulletLegendItemInterface[]>(
|
||||
props.categories.map((category, i) => ({
|
||||
name: category,
|
||||
color: colors.value[i],
|
||||
inactive: false
|
||||
}))
|
||||
);
|
||||
|
||||
const isMounted = useMounted()
|
||||
const isMounted = useMounted();
|
||||
|
||||
function handleLegendItemClick(d: BulletLegendItemInterface, i: number) {
|
||||
emits('legendItemClick', d, i)
|
||||
emits('legendItemClick', d, i);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')">
|
||||
<ChartLegend v-if="showLegend" v-model:items="legendItems" @legend-item-click="handleLegendItemClick" />
|
||||
<div :class="cn('flex h-[400px] w-full flex-col items-end', $attrs.class ?? '')">
|
||||
<ChartLegend
|
||||
v-if="showLegend"
|
||||
v-model:items="legendItems"
|
||||
@legend-item-click="handleLegendItemClick"
|
||||
/>
|
||||
|
||||
<VisXYContainer
|
||||
:margin="{ left: 20, right: 20 }"
|
||||
:data="data"
|
||||
:style="{ height: isMounted ? '100%' : 'auto' }"
|
||||
>
|
||||
<ChartCrosshair v-if="showTooltip" :colors="colors" :items="legendItems" :index="index" :custom-tooltip="customTooltip" />
|
||||
<VisXYContainer
|
||||
:margin="{ left: 20, right: 20 }"
|
||||
:data="data"
|
||||
:style="{ height: isMounted ? '100%' : 'auto' }"
|
||||
>
|
||||
<ChartCrosshair
|
||||
v-if="showTooltip"
|
||||
:colors="colors"
|
||||
:items="legendItems"
|
||||
:index="index"
|
||||
:custom-tooltip="customTooltip"
|
||||
/>
|
||||
|
||||
<template v-for="(category, i) in categories" :key="category">
|
||||
<VisLine
|
||||
:x="(d: Data, i: number) => i"
|
||||
:y="(d: Data) => d[category]"
|
||||
:curve-type="curveType"
|
||||
:color="colors[i]"
|
||||
:attributes="{
|
||||
[Line.selectors.line]: {
|
||||
opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,
|
||||
},
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
<template v-for="(category, i) in categories" :key="category">
|
||||
<VisLine
|
||||
:x="(d: Data, i: number) => i"
|
||||
:y="(d: Data) => d[category]"
|
||||
:curve-type="curveType"
|
||||
:color="colors[i]"
|
||||
:attributes="{
|
||||
[Line.selectors.line]: {
|
||||
opacity: legendItems.find(item => item.name === category)?.inactive
|
||||
? filterOpacity
|
||||
: 1
|
||||
}
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<VisAxis
|
||||
v-if="showXAxis"
|
||||
type="x"
|
||||
:tick-format="xFormatter ?? ((v: number) => data[v]?.[index])"
|
||||
:grid-line="false"
|
||||
:tick-line="false"
|
||||
tick-text-color="hsl(var(--vis-text-color))"
|
||||
/>
|
||||
<VisAxis
|
||||
v-if="showYAxis"
|
||||
type="y"
|
||||
:tick-line="false"
|
||||
:tick-format="yFormatter"
|
||||
:domain-line="false"
|
||||
:grid-line="showGridLine"
|
||||
:attributes="{
|
||||
[Axis.selectors.grid]: {
|
||||
class: 'text-muted',
|
||||
},
|
||||
}"
|
||||
tick-text-color="hsl(var(--vis-text-color))"
|
||||
/>
|
||||
<VisAxis
|
||||
v-if="showXAxis"
|
||||
type="x"
|
||||
:tick-format="xFormatter ?? ((v: number) => data[v]?.[index])"
|
||||
:grid-line="false"
|
||||
:tick-line="false"
|
||||
tick-text-color="hsl(var(--vis-text-color))"
|
||||
/>
|
||||
<VisAxis
|
||||
v-if="showYAxis"
|
||||
type="y"
|
||||
:tick-line="false"
|
||||
:tick-format="yFormatter"
|
||||
:domain-line="false"
|
||||
:grid-line="showGridLine"
|
||||
:attributes="{
|
||||
[Axis.selectors.grid]: {
|
||||
class: 'text-muted'
|
||||
}
|
||||
}"
|
||||
tick-text-color="hsl(var(--vis-text-color))"
|
||||
/>
|
||||
|
||||
<slot />
|
||||
</VisXYContainer>
|
||||
</div>
|
||||
<slot />
|
||||
</VisXYContainer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
export { default as LineChart } from './LineChart.vue'
|
||||
export { default as LineChart } from './LineChart.vue';
|
||||
|
||||
import type { Spacing } from '@unovis/ts'
|
||||
import type { Spacing } from '@unovis/ts';
|
||||
|
||||
type KeyOf<T extends Record<string, any>> = Extract<keyof T, string>
|
||||
type KeyOf<T extends Record<string, any>> = Extract<keyof T, string>;
|
||||
|
||||
export interface BaseChartProps<T extends Record<string, any>> {
|
||||
/**
|
||||
* The source data, in which each entry is a dictionary.
|
||||
*/
|
||||
data: T[]
|
||||
/**
|
||||
* Select the categories from your data. Used to populate the legend and toolip.
|
||||
*/
|
||||
categories: KeyOf<T>[]
|
||||
/**
|
||||
* Sets the key to map the data to the axis.
|
||||
*/
|
||||
index: KeyOf<T>
|
||||
/**
|
||||
* Change the default colors.
|
||||
*/
|
||||
colors?: string[]
|
||||
/**
|
||||
* Margin of each the container
|
||||
*/
|
||||
margin?: Spacing
|
||||
/**
|
||||
* Change the opacity of the non-selected field
|
||||
* @default 0.2
|
||||
*/
|
||||
filterOpacity?: number
|
||||
/**
|
||||
* Function to format X label
|
||||
*/
|
||||
xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string
|
||||
/**
|
||||
* Function to format Y label
|
||||
*/
|
||||
yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string
|
||||
/**
|
||||
* Controls the visibility of the X axis.
|
||||
* @default true
|
||||
*/
|
||||
showXAxis?: boolean
|
||||
/**
|
||||
* Controls the visibility of the Y axis.
|
||||
* @default true
|
||||
*/
|
||||
showYAxis?: boolean
|
||||
/**
|
||||
* Controls the visibility of tooltip.
|
||||
* @default true
|
||||
*/
|
||||
showTooltip?: boolean
|
||||
/**
|
||||
* Controls the visibility of legend.
|
||||
* @default true
|
||||
*/
|
||||
showLegend?: boolean
|
||||
/**
|
||||
* Controls the visibility of gridline.
|
||||
* @default true
|
||||
*/
|
||||
showGridLine?: boolean
|
||||
/**
|
||||
* The source data, in which each entry is a dictionary.
|
||||
*/
|
||||
data: T[];
|
||||
/**
|
||||
* Select the categories from your data. Used to populate the legend and toolip.
|
||||
*/
|
||||
categories: KeyOf<T>[];
|
||||
/**
|
||||
* Sets the key to map the data to the axis.
|
||||
*/
|
||||
index: KeyOf<T>;
|
||||
/**
|
||||
* Change the default colors.
|
||||
*/
|
||||
colors?: string[];
|
||||
/**
|
||||
* Margin of each the container
|
||||
*/
|
||||
margin?: Spacing;
|
||||
/**
|
||||
* Change the opacity of the non-selected field
|
||||
* @default 0.2
|
||||
*/
|
||||
filterOpacity?: number;
|
||||
/**
|
||||
* Function to format X label
|
||||
*/
|
||||
xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string;
|
||||
/**
|
||||
* Function to format Y label
|
||||
*/
|
||||
yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string;
|
||||
/**
|
||||
* Controls the visibility of the X axis.
|
||||
* @default true
|
||||
*/
|
||||
showXAxis?: boolean;
|
||||
/**
|
||||
* Controls the visibility of the Y axis.
|
||||
* @default true
|
||||
*/
|
||||
showYAxis?: boolean;
|
||||
/**
|
||||
* Controls the visibility of tooltip.
|
||||
* @default true
|
||||
*/
|
||||
showTooltip?: boolean;
|
||||
/**
|
||||
* Controls the visibility of legend.
|
||||
* @default true
|
||||
*/
|
||||
showLegend?: boolean;
|
||||
/**
|
||||
* Controls the visibility of gridline.
|
||||
* @default true
|
||||
*/
|
||||
showGridLine?: boolean;
|
||||
}
|
||||
|
||||
@@ -1,44 +1,48 @@
|
||||
<script setup lang="ts">
|
||||
import type { BulletLegendItemInterface } from '@unovis/ts'
|
||||
import { omit } from '@unovis/ts'
|
||||
import { VisCrosshair, VisTooltip } from '@unovis/vue'
|
||||
import { type Component, createApp } from 'vue'
|
||||
import { ChartTooltip } from '.'
|
||||
import type { BulletLegendItemInterface } from '@unovis/ts';
|
||||
import { omit } from '@unovis/ts';
|
||||
import { VisCrosshair, VisTooltip } from '@unovis/vue';
|
||||
import { type Component, createApp } from 'vue';
|
||||
import { ChartTooltip } from '.';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
colors: string[]
|
||||
index: string
|
||||
items: BulletLegendItemInterface[]
|
||||
customTooltip?: Component
|
||||
}>(), {
|
||||
colors: () => [],
|
||||
})
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
colors: string[];
|
||||
index: string;
|
||||
items: BulletLegendItemInterface[];
|
||||
customTooltip?: Component;
|
||||
}>(),
|
||||
{
|
||||
colors: () => []
|
||||
}
|
||||
);
|
||||
|
||||
// Use weakmap to store reference to each datapoint for Tooltip
|
||||
const wm = new WeakMap()
|
||||
const wm = new WeakMap();
|
||||
function template(d: any) {
|
||||
if (wm.has(d)) {
|
||||
return wm.get(d)
|
||||
}
|
||||
else {
|
||||
const componentDiv = document.createElement('div')
|
||||
const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {
|
||||
const legendReference = props.items.find(i => i.name === key)
|
||||
return { ...legendReference, value }
|
||||
})
|
||||
const TooltipComponent = props.customTooltip ?? ChartTooltip
|
||||
createApp(TooltipComponent, { title: d[props.index].toString(), data: omittedData }).mount(componentDiv)
|
||||
wm.set(d, componentDiv.innerHTML)
|
||||
return componentDiv.innerHTML
|
||||
}
|
||||
if (wm.has(d)) {
|
||||
return wm.get(d);
|
||||
} else {
|
||||
const componentDiv = document.createElement('div');
|
||||
const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {
|
||||
const legendReference = props.items.find(i => i.name === key);
|
||||
return { ...legendReference, value };
|
||||
});
|
||||
const TooltipComponent = props.customTooltip ?? ChartTooltip;
|
||||
createApp(TooltipComponent, { title: d[props.index].toString(), data: omittedData }).mount(
|
||||
componentDiv
|
||||
);
|
||||
wm.set(d, componentDiv.innerHTML);
|
||||
return componentDiv.innerHTML;
|
||||
}
|
||||
}
|
||||
|
||||
function color(d: unknown, i: number) {
|
||||
return props.colors[i] ?? 'transparent';
|
||||
return props.colors[i] ?? 'transparent';
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VisTooltip :horizontal-shift="20" :vertical-shift="20" />
|
||||
<VisCrosshair :template="template" :color="color" />
|
||||
<VisTooltip :horizontal-shift="20" :vertical-shift="20" />
|
||||
<VisCrosshair :template="template" :color="color" />
|
||||
</template>
|
||||
|
||||
@@ -1,50 +1,57 @@
|
||||
<script setup lang="ts">
|
||||
import type { BulletLegendItemInterface } from '@unovis/ts'
|
||||
import { buttonVariants } from '@/components/ui/button'
|
||||
import { BulletLegend } from '@unovis/ts'
|
||||
import { VisBulletLegend } from '@unovis/vue'
|
||||
import { nextTick, onMounted, ref } from 'vue'
|
||||
import { buttonVariants } from '@/components/ui/button';
|
||||
import type { BulletLegendItemInterface } from '@unovis/ts';
|
||||
import { BulletLegend } from '@unovis/ts';
|
||||
import { VisBulletLegend } from '@unovis/vue';
|
||||
import { nextTick, onMounted, ref } from 'vue';
|
||||
|
||||
const props = withDefaults(defineProps<{ items: BulletLegendItemInterface[] }>(), {
|
||||
items: () => [],
|
||||
})
|
||||
items: () => []
|
||||
});
|
||||
|
||||
const emits = defineEmits<{
|
||||
'legendItemClick': [d: BulletLegendItemInterface, i: number]
|
||||
'update:items': [payload: BulletLegendItemInterface[]]
|
||||
}>()
|
||||
legendItemClick: [d: BulletLegendItemInterface, i: number];
|
||||
'update:items': [payload: BulletLegendItemInterface[]];
|
||||
}>();
|
||||
|
||||
const elRef = ref<HTMLElement>()
|
||||
const elRef = ref<HTMLElement>();
|
||||
|
||||
onMounted(() => {
|
||||
const selector = `.${BulletLegend.selectors.item}`
|
||||
nextTick(() => {
|
||||
const elements = elRef.value?.querySelectorAll(selector)
|
||||
const classes = buttonVariants({ variant: 'ghost', size: 'xs' }).split(' ')
|
||||
elements?.forEach(el => el.classList.add(...classes, '!inline-flex', '!mr-2'))
|
||||
})
|
||||
})
|
||||
const selector = `.${BulletLegend.selectors.item}`;
|
||||
nextTick(() => {
|
||||
const elements = elRef.value?.querySelectorAll(selector);
|
||||
const classes = buttonVariants({ variant: 'ghost', size: 'xs' }).split(' ');
|
||||
elements?.forEach(el => el.classList.add(...classes, '!inline-flex', '!mr-2'));
|
||||
});
|
||||
});
|
||||
|
||||
function onLegendItemClick(d: BulletLegendItemInterface, i: number) {
|
||||
emits('legendItemClick', d, i)
|
||||
const isBulletActive = !props.items[i].inactive
|
||||
const isFilterApplied = props.items.some(i => i.inactive)
|
||||
if (isFilterApplied && isBulletActive) {
|
||||
// reset filter
|
||||
emits('update:items', props.items.map(item => ({ ...item, inactive: false })))
|
||||
}
|
||||
else {
|
||||
// apply selection, set other item as inactive
|
||||
emits('update:items', props.items.map(item => item.name === d.name ? ({ ...d, inactive: false }) : { ...item, inactive: true }))
|
||||
}
|
||||
emits('legendItemClick', d, i);
|
||||
const isBulletActive = !props.items[i].inactive;
|
||||
const isFilterApplied = props.items.some(i => i.inactive);
|
||||
if (isFilterApplied && isBulletActive) {
|
||||
// reset filter
|
||||
emits(
|
||||
'update:items',
|
||||
props.items.map(item => ({ ...item, inactive: false }))
|
||||
);
|
||||
} else {
|
||||
// apply selection, set other item as inactive
|
||||
emits(
|
||||
'update:items',
|
||||
props.items.map(item =>
|
||||
item.name === d.name ? { ...d, inactive: false } : { ...item, inactive: true }
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="elRef" class="w-max">
|
||||
<VisBulletLegend
|
||||
:items="items"
|
||||
:on-legend-item-click="onLegendItemClick"
|
||||
/>
|
||||
</div>
|
||||
<div ref="elRef" class="w-max">
|
||||
<ScrollArea class="mb-2 ms-40 w-screen whitespace-nowrap rounded-md border">
|
||||
<VisBulletLegend :items="items" :on-legend-item-click="onLegendItemClick" class="ms-10" />
|
||||
<ScrollBar orientation="horizontal" />
|
||||
</ScrollArea>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,63 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
import type { BulletLegendItemInterface } from '@unovis/ts'
|
||||
import { omit } from '@unovis/ts'
|
||||
import { VisTooltip } from '@unovis/vue'
|
||||
import { type Component, createApp } from 'vue'
|
||||
import { ChartTooltip } from '.'
|
||||
import type { BulletLegendItemInterface } from '@unovis/ts';
|
||||
import { omit } from '@unovis/ts';
|
||||
import { VisTooltip } from '@unovis/vue';
|
||||
import { type Component, createApp } from 'vue';
|
||||
import { ChartTooltip } from '.';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
selector: string
|
||||
index: string
|
||||
items?: BulletLegendItemInterface[]
|
||||
valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string
|
||||
customTooltip?: Component
|
||||
}>(), {
|
||||
valueFormatter: (tick: number) => `${tick}`,
|
||||
})
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
selector: string;
|
||||
index: string;
|
||||
items?: BulletLegendItemInterface[];
|
||||
valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string;
|
||||
customTooltip?: Component;
|
||||
}>(),
|
||||
{
|
||||
valueFormatter: (tick: number) => `${tick}`
|
||||
}
|
||||
);
|
||||
|
||||
// Use weakmap to store reference to each datapoint for Tooltip
|
||||
const wm = new WeakMap()
|
||||
const wm = new WeakMap();
|
||||
function template(d: any, i: number, elements: (HTMLElement | SVGElement)[]) {
|
||||
if (props.index in d) {
|
||||
if (wm.has(d)) {
|
||||
return wm.get(d)
|
||||
}
|
||||
else {
|
||||
const componentDiv = document.createElement('div')
|
||||
const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {
|
||||
const legendReference = props.items?.find(i => i.name === key)
|
||||
return { ...legendReference, value: props.valueFormatter(value) }
|
||||
})
|
||||
const TooltipComponent = props.customTooltip ?? ChartTooltip
|
||||
createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv)
|
||||
wm.set(d, componentDiv.innerHTML)
|
||||
return componentDiv.innerHTML
|
||||
}
|
||||
}
|
||||
if (props.index in d) {
|
||||
if (wm.has(d)) {
|
||||
return wm.get(d);
|
||||
} else {
|
||||
const componentDiv = document.createElement('div');
|
||||
const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {
|
||||
const legendReference = props.items?.find(i => i.name === key);
|
||||
return { ...legendReference, value: props.valueFormatter(value) };
|
||||
});
|
||||
const TooltipComponent = props.customTooltip ?? ChartTooltip;
|
||||
createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv);
|
||||
wm.set(d, componentDiv.innerHTML);
|
||||
return componentDiv.innerHTML;
|
||||
}
|
||||
} else {
|
||||
const data = d.data;
|
||||
|
||||
else {
|
||||
const data = d.data
|
||||
|
||||
if (wm.has(data)) {
|
||||
return wm.get(data)
|
||||
}
|
||||
else {
|
||||
const style = getComputedStyle(elements[i])
|
||||
const omittedData = [{ name: data.name, value: props.valueFormatter(data[props.index]), color: style.fill }]
|
||||
const componentDiv = document.createElement('div')
|
||||
const TooltipComponent = props.customTooltip ?? ChartTooltip
|
||||
createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv)
|
||||
wm.set(d, componentDiv.innerHTML)
|
||||
return componentDiv.innerHTML
|
||||
}
|
||||
}
|
||||
if (wm.has(data)) {
|
||||
return wm.get(data);
|
||||
} else {
|
||||
const style = getComputedStyle(elements[i]);
|
||||
const omittedData = [
|
||||
{ name: data.name, value: props.valueFormatter(data[props.index]), color: style.fill }
|
||||
];
|
||||
const componentDiv = document.createElement('div');
|
||||
const TooltipComponent = props.customTooltip ?? ChartTooltip;
|
||||
createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv);
|
||||
wm.set(d, componentDiv.innerHTML);
|
||||
return componentDiv.innerHTML;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VisTooltip
|
||||
:horizontal-shift="20" :vertical-shift="20" :triggers="{
|
||||
[selector]: template,
|
||||
}"
|
||||
/>
|
||||
<VisTooltip
|
||||
:horizontal-shift="20"
|
||||
:vertical-shift="20"
|
||||
:triggers="{
|
||||
[selector]: template
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
|
||||
defineProps<{
|
||||
title?: string
|
||||
data: {
|
||||
name: string
|
||||
color: string
|
||||
value: any
|
||||
}[]
|
||||
}>()
|
||||
title?: string;
|
||||
data: {
|
||||
name: string;
|
||||
color: string;
|
||||
value: any;
|
||||
}[];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Card class="text-sm">
|
||||
<CardHeader v-if="title" class="p-3 border-b">
|
||||
<CardTitle>
|
||||
{{ title }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="p-3 min-w-[180px] flex flex-col gap-1">
|
||||
<div v-for="(item, key) in data" :key="key" class="flex justify-between">
|
||||
<div class="flex items-center">
|
||||
<span class="w-2.5 h-2.5 mr-2">
|
||||
<svg width="100%" height="100%" viewBox="0 0 30 30">
|
||||
<path
|
||||
d=" M 15 15 m -14, 0 a 14,14 0 1,1 28,0 a 14,14 0 1,1 -28,0"
|
||||
:stroke="item.color"
|
||||
:fill="item.color"
|
||||
stroke-width="1"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
<span class="font-semibold ml-4">{{ item.value }}</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card class="text-sm">
|
||||
<CardHeader v-if="title" class="border-b p-3">
|
||||
<CardTitle>
|
||||
{{ title }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="flex min-w-[180px] flex-col gap-1 p-3">
|
||||
<div v-for="(item, key) in data" :key="key" class="flex justify-between">
|
||||
<div class="flex items-center">
|
||||
<span class="mr-2 h-2.5 w-2.5">
|
||||
<svg width="100%" height="100%" viewBox="0 0 30 30">
|
||||
<path
|
||||
d=" M 15 15 m -14, 0 a 14,14 0 1,1 28,0 a 14,14 0 1,1 -28,0"
|
||||
:stroke="item.color"
|
||||
:fill="item.color"
|
||||
stroke-width="1"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
<span class="ml-4 font-semibold">{{ item.value }}</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
export { default as ChartCrosshair } from './ChartCrosshair.vue'
|
||||
export { default as ChartLegend } from './ChartLegend.vue'
|
||||
export { default as ChartSingleTooltip } from './ChartSingleTooltip.vue'
|
||||
export { default as ChartTooltip } from './ChartTooltip.vue'
|
||||
export { default as ChartCrosshair } from './ChartCrosshair.vue';
|
||||
export { default as ChartLegend } from './ChartLegend.vue';
|
||||
export { default as ChartSingleTooltip } from './ChartSingleTooltip.vue';
|
||||
export { default as ChartTooltip } from './ChartTooltip.vue';
|
||||
|
||||
export function defaultColors(count: number = 3) {
|
||||
const quotient = Math.floor(count / 2)
|
||||
const remainder = count % 2
|
||||
const quotient = Math.floor(count / 2);
|
||||
const remainder = count % 2;
|
||||
|
||||
const primaryCount = quotient + remainder
|
||||
const secondaryCount = quotient
|
||||
return [
|
||||
...Array.from(new Array(primaryCount).keys()).map(i => `hsl(var(--vis-primary-color) / ${1 - (1 / primaryCount) * i})`),
|
||||
...Array.from(new Array(secondaryCount).keys()).map(i => `hsl(var(--vis-secondary-color) / ${1 - (1 / secondaryCount) * i})`),
|
||||
];
|
||||
const primaryCount = quotient + remainder;
|
||||
const secondaryCount = quotient;
|
||||
return [
|
||||
...Array.from(new Array(primaryCount).keys()).map(
|
||||
i => `hsl(var(--vis-primary-color) / ${1 - (1 / primaryCount) * i})`
|
||||
),
|
||||
...Array.from(new Array(secondaryCount).keys()).map(
|
||||
i => `hsl(var(--vis-secondary-color) / ${1 - (1 / secondaryCount) * i})`
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
export * from './interface'
|
||||
export * from './interface';
|
||||
|
||||
@@ -1,64 +1,64 @@
|
||||
import type { Spacing } from '@unovis/ts'
|
||||
import type { Spacing } from '@unovis/ts';
|
||||
|
||||
type KeyOf<T extends Record<string, any>> = Extract<keyof T, string>
|
||||
type KeyOf<T extends Record<string, any>> = Extract<keyof T, string>;
|
||||
|
||||
export interface BaseChartProps<T extends Record<string, any>> {
|
||||
/**
|
||||
* The source data, in which each entry is a dictionary.
|
||||
*/
|
||||
data: T[]
|
||||
/**
|
||||
* Select the categories from your data. Used to populate the legend and toolip.
|
||||
*/
|
||||
categories: KeyOf<T>[]
|
||||
/**
|
||||
* Sets the key to map the data to the axis.
|
||||
*/
|
||||
index: KeyOf<T>
|
||||
/**
|
||||
* Change the default colors.
|
||||
*/
|
||||
colors?: string[]
|
||||
/**
|
||||
* Margin of each the container
|
||||
*/
|
||||
margin?: Spacing
|
||||
/**
|
||||
* Change the opacity of the non-selected field
|
||||
* @default 0.2
|
||||
*/
|
||||
filterOpacity?: number
|
||||
/**
|
||||
* Function to format X label
|
||||
*/
|
||||
xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string
|
||||
/**
|
||||
* Function to format Y label
|
||||
*/
|
||||
yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string
|
||||
/**
|
||||
* Controls the visibility of the X axis.
|
||||
* @default true
|
||||
*/
|
||||
showXAxis?: boolean
|
||||
/**
|
||||
* Controls the visibility of the Y axis.
|
||||
* @default true
|
||||
*/
|
||||
showYAxis?: boolean
|
||||
/**
|
||||
* Controls the visibility of tooltip.
|
||||
* @default true
|
||||
*/
|
||||
showTooltip?: boolean
|
||||
/**
|
||||
* Controls the visibility of legend.
|
||||
* @default true
|
||||
*/
|
||||
showLegend?: boolean
|
||||
/**
|
||||
* Controls the visibility of gridline.
|
||||
* @default true
|
||||
*/
|
||||
showGridLine?: boolean
|
||||
/**
|
||||
* The source data, in which each entry is a dictionary.
|
||||
*/
|
||||
data: T[];
|
||||
/**
|
||||
* Select the categories from your data. Used to populate the legend and toolip.
|
||||
*/
|
||||
categories: KeyOf<T>[];
|
||||
/**
|
||||
* Sets the key to map the data to the axis.
|
||||
*/
|
||||
index: KeyOf<T>;
|
||||
/**
|
||||
* Change the default colors.
|
||||
*/
|
||||
colors?: string[];
|
||||
/**
|
||||
* Margin of each the container
|
||||
*/
|
||||
margin?: Spacing;
|
||||
/**
|
||||
* Change the opacity of the non-selected field
|
||||
* @default 0.2
|
||||
*/
|
||||
filterOpacity?: number;
|
||||
/**
|
||||
* Function to format X label
|
||||
*/
|
||||
xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string;
|
||||
/**
|
||||
* Function to format Y label
|
||||
*/
|
||||
yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string;
|
||||
/**
|
||||
* Controls the visibility of the X axis.
|
||||
* @default true
|
||||
*/
|
||||
showXAxis?: boolean;
|
||||
/**
|
||||
* Controls the visibility of the Y axis.
|
||||
* @default true
|
||||
*/
|
||||
showYAxis?: boolean;
|
||||
/**
|
||||
* Controls the visibility of tooltip.
|
||||
* @default true
|
||||
*/
|
||||
showTooltip?: boolean;
|
||||
/**
|
||||
* Controls the visibility of legend.
|
||||
* @default true
|
||||
*/
|
||||
showLegend?: boolean;
|
||||
/**
|
||||
* Controls the visibility of gridline.
|
||||
* @default true
|
||||
*/
|
||||
showGridLine?: boolean;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { DialogRoot, type DialogRootEmits, type DialogRootProps, useForwardPropsEmits } from 'radix-vue'
|
||||
import {
|
||||
DialogRoot,
|
||||
type DialogRootEmits,
|
||||
type DialogRootProps,
|
||||
useForwardPropsEmits
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<DialogRootProps>()
|
||||
const emits = defineEmits<DialogRootEmits>()
|
||||
const props = defineProps<DialogRootProps>();
|
||||
const emits = defineEmits<DialogRootEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits)
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogRoot v-bind="forwarded">
|
||||
<slot />
|
||||
</DialogRoot>
|
||||
<DialogRoot v-bind="forwarded">
|
||||
<slot />
|
||||
</DialogRoot>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { DialogClose, type DialogCloseProps } from 'radix-vue'
|
||||
import { DialogClose, type DialogCloseProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<DialogCloseProps>()
|
||||
const props = defineProps<DialogCloseProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogClose v-bind="props">
|
||||
<slot />
|
||||
</DialogClose>
|
||||
<DialogClose v-bind="props">
|
||||
<slot />
|
||||
</DialogClose>
|
||||
</template>
|
||||
|
||||
@@ -1,50 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils'
|
||||
import { X } from 'lucide-vue-next'
|
||||
import { cn } from '@/lib/utils';
|
||||
import { X } from 'lucide-vue-next';
|
||||
import {
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
type DialogContentEmits,
|
||||
type DialogContentProps,
|
||||
DialogOverlay,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
type DialogContentEmits,
|
||||
type DialogContentProps,
|
||||
DialogOverlay,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits
|
||||
} from 'radix-vue';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
|
||||
const emits = defineEmits<DialogContentEmits>()
|
||||
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>();
|
||||
const emits = defineEmits<DialogContentEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated
|
||||
})
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogPortal>
|
||||
<DialogOverlay
|
||||
class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
/>
|
||||
<DialogContent
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||
props.class,
|
||||
)"
|
||||
>
|
||||
<slot />
|
||||
<DialogPortal>
|
||||
<DialogOverlay
|
||||
class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
/>
|
||||
<DialogContent
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
|
||||
<DialogClose
|
||||
class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"
|
||||
>
|
||||
<X class="w-4 h-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogPortal>
|
||||
<DialogClose
|
||||
class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"
|
||||
>
|
||||
<X class="h-4 w-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogPortal>
|
||||
</template>
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils'
|
||||
import { DialogDescription, type DialogDescriptionProps, useForwardProps } from 'radix-vue'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils';
|
||||
import { DialogDescription, type DialogDescriptionProps, useForwardProps } from 'radix-vue';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>()
|
||||
const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated
|
||||
})
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps)
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogDescription
|
||||
v-bind="forwardedProps"
|
||||
:class="cn('text-sm text-muted-foreground', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</DialogDescription>
|
||||
<DialogDescription
|
||||
v-bind="forwardedProps"
|
||||
:class="cn('text-sm text-muted-foreground', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</DialogDescription>
|
||||
</template>
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<{ class?: HTMLAttributes['class'] }>()
|
||||
const props = defineProps<{ class?: HTMLAttributes['class'] }>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
<div :class="cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
class?: HTMLAttributes['class'];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="cn('flex flex-col gap-y-1.5 text-center sm:text-left', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
<div :class="cn('flex flex-col gap-y-1.5 text-center sm:text-left', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,59 +1,64 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils'
|
||||
import { X } from 'lucide-vue-next'
|
||||
import { cn } from '@/lib/utils';
|
||||
import { X } from 'lucide-vue-next';
|
||||
import {
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
type DialogContentEmits,
|
||||
type DialogContentProps,
|
||||
DialogOverlay,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
type DialogContentEmits,
|
||||
type DialogContentProps,
|
||||
DialogOverlay,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits
|
||||
} from 'radix-vue';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
|
||||
const emits = defineEmits<DialogContentEmits>()
|
||||
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>();
|
||||
const emits = defineEmits<DialogContentEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated
|
||||
})
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogPortal>
|
||||
<DialogOverlay
|
||||
class="fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
>
|
||||
<DialogContent
|
||||
:class="
|
||||
cn(
|
||||
'relative z-50 grid w-full max-w-lg my-8 gap-4 border border-border bg-background p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
v-bind="forwarded"
|
||||
@pointer-down-outside="(event) => {
|
||||
const originalEvent = event.detail.originalEvent;
|
||||
const target = originalEvent.target as HTMLElement;
|
||||
if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}"
|
||||
>
|
||||
<slot />
|
||||
<DialogPortal>
|
||||
<DialogOverlay
|
||||
class="fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
>
|
||||
<DialogContent
|
||||
:class="
|
||||
cn(
|
||||
'relative z-50 my-8 grid w-full max-w-lg gap-4 border border-border bg-background p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
v-bind="forwarded"
|
||||
@pointer-down-outside="
|
||||
event => {
|
||||
const originalEvent = event.detail.originalEvent;
|
||||
const target = originalEvent.target as HTMLElement;
|
||||
if (
|
||||
originalEvent.offsetX > target.clientWidth ||
|
||||
originalEvent.offsetY > target.clientHeight
|
||||
) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
|
||||
<DialogClose
|
||||
class="absolute top-3 right-3 p-0.5 transition-colors rounded-md hover:bg-secondary"
|
||||
>
|
||||
<X class="w-4 h-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogOverlay>
|
||||
</DialogPortal>
|
||||
<DialogClose
|
||||
class="absolute right-3 top-3 rounded-md p-0.5 transition-colors hover:bg-secondary"
|
||||
>
|
||||
<X class="h-4 w-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogOverlay>
|
||||
</DialogPortal>
|
||||
</template>
|
||||
|
||||
@@ -1,29 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils'
|
||||
import { DialogTitle, type DialogTitleProps, useForwardProps } from 'radix-vue'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils';
|
||||
import { DialogTitle, type DialogTitleProps, useForwardProps } from 'radix-vue';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>()
|
||||
const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated
|
||||
})
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps)
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogTitle
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'text-lg font-semibold leading-none tracking-tight',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</DialogTitle>
|
||||
<DialogTitle
|
||||
v-bind="forwardedProps"
|
||||
:class="cn('text-lg font-semibold leading-none tracking-tight', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</DialogTitle>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { DialogTrigger, type DialogTriggerProps } from 'radix-vue'
|
||||
import { DialogTrigger, type DialogTriggerProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<DialogTriggerProps>()
|
||||
const props = defineProps<DialogTriggerProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogTrigger v-bind="props">
|
||||
<slot />
|
||||
</DialogTrigger>
|
||||
<DialogTrigger v-bind="props">
|
||||
<slot />
|
||||
</DialogTrigger>
|
||||
</template>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
export { default as Dialog } from './Dialog.vue'
|
||||
export { default as DialogClose } from './DialogClose.vue'
|
||||
export { default as DialogContent } from './DialogContent.vue'
|
||||
export { default as DialogDescription } from './DialogDescription.vue'
|
||||
export { default as DialogFooter } from './DialogFooter.vue'
|
||||
export { default as DialogHeader } from './DialogHeader.vue'
|
||||
export { default as DialogScrollContent } from './DialogScrollContent.vue'
|
||||
export { default as DialogTitle } from './DialogTitle.vue'
|
||||
export { default as DialogTrigger } from './DialogTrigger.vue'
|
||||
export { default as Dialog } from './Dialog.vue';
|
||||
export { default as DialogClose } from './DialogClose.vue';
|
||||
export { default as DialogContent } from './DialogContent.vue';
|
||||
export { default as DialogDescription } from './DialogDescription.vue';
|
||||
export { default as DialogFooter } from './DialogFooter.vue';
|
||||
export { default as DialogHeader } from './DialogHeader.vue';
|
||||
export { default as DialogScrollContent } from './DialogScrollContent.vue';
|
||||
export { default as DialogTitle } from './DialogTitle.vue';
|
||||
export { default as DialogTrigger } from './DialogTrigger.vue';
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import type { NumberFieldRootEmits, NumberFieldRootProps } from 'radix-vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { NumberFieldRoot, useForwardPropsEmits } from 'radix-vue'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { NumberFieldRootEmits, NumberFieldRootProps } from 'radix-vue';
|
||||
import { NumberFieldRoot, useForwardPropsEmits } from 'radix-vue';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<NumberFieldRootProps & { class?: HTMLAttributes['class'] }>()
|
||||
const emits = defineEmits<NumberFieldRootEmits>()
|
||||
const props = defineProps<NumberFieldRootProps & { class?: HTMLAttributes['class'] }>();
|
||||
const emits = defineEmits<NumberFieldRootEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated
|
||||
})
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldRoot v-bind="forwarded" :class="cn('grid gap-1.5', props.class)">
|
||||
<slot />
|
||||
</NumberFieldRoot>
|
||||
<NumberFieldRoot v-bind="forwarded" :class="cn('grid gap-1.5', props.class)">
|
||||
<slot />
|
||||
</NumberFieldRoot>
|
||||
</template>
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
class?: HTMLAttributes['class'];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('relative [&>[data-slot=input]]:has-[[data-slot=increment]]:pr-5 [&>[data-slot=input]]:has-[[data-slot=decrement]]:pl-5', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'relative [&>[data-slot=input]]:has-[[data-slot=decrement]]:pl-5 [&>[data-slot=input]]:has-[[data-slot=increment]]:pr-5',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
import type { NumberFieldDecrementProps } from 'radix-vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Minus } from 'lucide-vue-next'
|
||||
import { NumberFieldDecrement, useForwardProps } from 'radix-vue'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Minus } from 'lucide-vue-next';
|
||||
import type { NumberFieldDecrementProps } from 'radix-vue';
|
||||
import { NumberFieldDecrement, useForwardProps } from 'radix-vue';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<NumberFieldDecrementProps & { class?: HTMLAttributes['class'] }>()
|
||||
const props = defineProps<NumberFieldDecrementProps & { class?: HTMLAttributes['class'] }>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated
|
||||
})
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardProps(delegatedProps)
|
||||
const forwarded = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldDecrement data-slot="decrement" v-bind="forwarded" :class="cn('absolute top-1/2 -translate-y-1/2 left-0 p-3 disabled:cursor-not-allowed disabled:opacity-20', props.class)">
|
||||
<slot>
|
||||
<Minus class="h-4 w-4" />
|
||||
</slot>
|
||||
</NumberFieldDecrement>
|
||||
<NumberFieldDecrement
|
||||
data-slot="decrement"
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'absolute left-0 top-1/2 -translate-y-1/2 p-3 disabled:cursor-not-allowed disabled:opacity-20',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot>
|
||||
<Minus class="h-4 w-4" />
|
||||
</slot>
|
||||
</NumberFieldDecrement>
|
||||
</template>
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
import type { NumberFieldIncrementProps } from 'radix-vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Plus } from 'lucide-vue-next'
|
||||
import { NumberFieldIncrement, useForwardProps } from 'radix-vue'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Plus } from 'lucide-vue-next';
|
||||
import type { NumberFieldIncrementProps } from 'radix-vue';
|
||||
import { NumberFieldIncrement, useForwardProps } from 'radix-vue';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<NumberFieldIncrementProps & { class?: HTMLAttributes['class'] }>()
|
||||
const props = defineProps<NumberFieldIncrementProps & { class?: HTMLAttributes['class'] }>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated
|
||||
})
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardProps(delegatedProps)
|
||||
const forwarded = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldIncrement data-slot="increment" v-bind="forwarded" :class="cn('absolute top-1/2 -translate-y-1/2 right-0 disabled:cursor-not-allowed disabled:opacity-20 p-3', props.class)">
|
||||
<slot>
|
||||
<Plus class="h-4 w-4" />
|
||||
</slot>
|
||||
</NumberFieldIncrement>
|
||||
<NumberFieldIncrement
|
||||
data-slot="increment"
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'absolute right-0 top-1/2 -translate-y-1/2 p-3 disabled:cursor-not-allowed disabled:opacity-20',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot>
|
||||
<Plus class="h-4 w-4" />
|
||||
</slot>
|
||||
</NumberFieldIncrement>
|
||||
</template>
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { NumberFieldInput } from 'radix-vue'
|
||||
import { cn } from '@/lib/utils';
|
||||
import { NumberFieldInput } from 'radix-vue';
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
class?: HTMLAttributes['class'];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldInput
|
||||
data-slot="input"
|
||||
:class="cn('flex h-10 w-full rounded-md border border-input bg-background py-2 text-sm text-center ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class)"
|
||||
/>
|
||||
<NumberFieldInput
|
||||
data-slot="input"
|
||||
:class="
|
||||
cn(
|
||||
'flex h-10 w-full rounded-md border border-input bg-background py-2 text-center text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export { default as NumberField } from './NumberField.vue'
|
||||
export { default as NumberFieldContent } from './NumberFieldContent.vue'
|
||||
export { default as NumberFieldDecrement } from './NumberFieldDecrement.vue'
|
||||
export { default as NumberFieldIncrement } from './NumberFieldIncrement.vue'
|
||||
export { default as NumberFieldInput } from './NumberFieldInput.vue'
|
||||
export { default as NumberField } from './NumberField.vue';
|
||||
export { default as NumberFieldContent } from './NumberFieldContent.vue';
|
||||
export { default as NumberFieldDecrement } from './NumberFieldDecrement.vue';
|
||||
export { default as NumberFieldIncrement } from './NumberFieldIncrement.vue';
|
||||
export { default as NumberFieldInput } from './NumberFieldInput.vue';
|
||||
|
||||
45
src/components/ui/switch/Switch.vue
Normal file
45
src/components/ui/switch/Switch.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils';
|
||||
import {
|
||||
SwitchRoot,
|
||||
type SwitchRootEmits,
|
||||
type SwitchRootProps,
|
||||
SwitchThumb,
|
||||
useForwardPropsEmits
|
||||
} from 'radix-vue';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>();
|
||||
|
||||
const emits = defineEmits<SwitchRootEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SwitchRoot
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<SwitchThumb
|
||||
:class="
|
||||
cn(
|
||||
'pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5'
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot name="thumb" />
|
||||
</SwitchThumb>
|
||||
</SwitchRoot>
|
||||
</template>
|
||||
1
src/components/ui/switch/index.ts
Normal file
1
src/components/ui/switch/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Switch } from './Switch.vue';
|
||||
@@ -5,10 +5,10 @@ export { default as Toast } from './Toast.vue';
|
||||
export { default as ToastAction } from './ToastAction.vue';
|
||||
export { default as ToastClose } from './ToastClose.vue';
|
||||
export { default as ToastDescription } from './ToastDescription.vue';
|
||||
export { default as Toaster } from './Toaster.vue';
|
||||
export { default as ToastProvider } from './ToastProvider.vue';
|
||||
export { default as ToastTitle } from './ToastTitle.vue';
|
||||
export { default as ToastViewport } from './ToastViewport.vue';
|
||||
export { default as Toaster } from './Toaster.vue';
|
||||
export { toast, useToast } from './use-toast';
|
||||
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
|
||||
@@ -3,68 +3,9 @@ useHead({
|
||||
title: "Garand's WG | Wykresy i statystyki"
|
||||
});
|
||||
|
||||
interface DataForCharts {
|
||||
states: {
|
||||
config: Config;
|
||||
burgs: ChartData[];
|
||||
provinces: ChartData[];
|
||||
cells: ChartData[];
|
||||
culturesCells: ChartData[];
|
||||
religionCells: ChartData[];
|
||||
biomesCells: ChartData[];
|
||||
ruralPopulation: ChartData[];
|
||||
urbanPopulation: ChartData[];
|
||||
forms: ChartData[];
|
||||
};
|
||||
provinces: {
|
||||
config: Config;
|
||||
burgs: ChartData[];
|
||||
cells: ChartData[];
|
||||
ruralPopulation: ChartData[];
|
||||
urbanPopulation: ChartData[];
|
||||
forms: ChartData[];
|
||||
};
|
||||
burgs: {
|
||||
config: Config;
|
||||
population: ChartData[];
|
||||
religions: ChartData[];
|
||||
cultures: ChartData[];
|
||||
capitals: ChartData[];
|
||||
ports: ChartData[];
|
||||
cities: ChartData[];
|
||||
walls: ChartData[];
|
||||
plazas: ChartData[];
|
||||
temples: ChartData[];
|
||||
shantyTowns: ChartData[];
|
||||
};
|
||||
cultures: {
|
||||
config: Config;
|
||||
cells: ChartData[];
|
||||
population: ChartData[];
|
||||
types: ChartData[];
|
||||
namesbases: ChartData[];
|
||||
};
|
||||
religions: {
|
||||
config: Config;
|
||||
cells: ChartData[];
|
||||
population: ChartData[];
|
||||
types: ChartData[];
|
||||
forms: ChartData[];
|
||||
};
|
||||
}
|
||||
import type { ChartData, Config, DataForCharts } from '@/types/chartsTypes';
|
||||
|
||||
interface ChartData {
|
||||
turn: number;
|
||||
[key: string]: number;
|
||||
}
|
||||
|
||||
interface Config {
|
||||
categories: string[];
|
||||
colors?: string[];
|
||||
}
|
||||
|
||||
const pb = usePocketBase();
|
||||
const data = useChartsAndStatsStore();
|
||||
const data = cacheFullListResponses();
|
||||
|
||||
const turnsData = await data.fetchTurnsData();
|
||||
const statesData = await data.fetchStatesData();
|
||||
@@ -76,50 +17,55 @@ const religionsData = await data.fetchReligionsData();
|
||||
const dataForCharts: DataForCharts = {
|
||||
states: {
|
||||
config: { categories: [], colors: [] },
|
||||
burgs: [],
|
||||
provinces: [],
|
||||
cells: [],
|
||||
culturesCells: [],
|
||||
religionCells: [],
|
||||
biomesCells: [],
|
||||
ruralPopulation: [],
|
||||
urbanPopulation: [],
|
||||
forms: []
|
||||
charts: {
|
||||
burgs: [],
|
||||
provinces: [],
|
||||
cells: [],
|
||||
ruralPopulation: [],
|
||||
urbanPopulation: []
|
||||
}
|
||||
},
|
||||
provinces: {
|
||||
config: { categories: [], colors: [] },
|
||||
burgs: [],
|
||||
cells: [],
|
||||
ruralPopulation: [],
|
||||
urbanPopulation: [],
|
||||
forms: []
|
||||
charts: {
|
||||
burgs: [],
|
||||
cells: [],
|
||||
ruralPopulation: [],
|
||||
urbanPopulation: []
|
||||
}
|
||||
},
|
||||
burgs: {
|
||||
config: { categories: [], colors: [] },
|
||||
population: [],
|
||||
religions: [],
|
||||
cultures: [],
|
||||
capitals: [],
|
||||
ports: [],
|
||||
cities: [],
|
||||
walls: [],
|
||||
plazas: [],
|
||||
temples: [],
|
||||
shantyTowns: []
|
||||
charts: {
|
||||
population: [],
|
||||
religions: [],
|
||||
cultures: [],
|
||||
capitals: [],
|
||||
ports: [],
|
||||
cities: [],
|
||||
walls: [],
|
||||
plazas: [],
|
||||
temples: [],
|
||||
shantyTowns: []
|
||||
}
|
||||
},
|
||||
cultures: {
|
||||
config: { categories: [], colors: [] },
|
||||
cells: [],
|
||||
population: [],
|
||||
types: [],
|
||||
namesbases: []
|
||||
charts: {
|
||||
cells: [],
|
||||
population: [],
|
||||
types: [],
|
||||
namesbases: []
|
||||
}
|
||||
},
|
||||
religions: {
|
||||
config: { categories: [], colors: [] },
|
||||
cells: [],
|
||||
population: [],
|
||||
types: [],
|
||||
forms: []
|
||||
charts: {
|
||||
cells: [],
|
||||
population: [],
|
||||
types: [],
|
||||
forms: []
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -139,67 +85,61 @@ for (let i = 0; i < configsDataSets.length; i++) {
|
||||
if (dataset.data[0].color) config.colors = dataset.data.map(item => item.color);
|
||||
}
|
||||
|
||||
for (let i = 0; i < turnsData.length - 1; i++) {
|
||||
for (let i = 0; i < turnsData.length - 0; i++) {
|
||||
const turn = turnsData[i];
|
||||
const statesBurgsDataItem: ChartData = { turn: turn.value };
|
||||
const statesProvincesDataItem: ChartData = { turn: turn.value };
|
||||
const statesCellsDataItem: ChartData = { turn: turn.value };
|
||||
const culturesCellsDataItem: ChartData = { turn: turn.value };
|
||||
const religionCellsDataItem: ChartData = { turn: turn.value };
|
||||
const biomesCellsDataItem: ChartData = { turn: turn.value };
|
||||
const ruralPopulationDataItem: ChartData = { turn: turn.value };
|
||||
const urbanPopulationDataItem: ChartData = { turn: turn.value };
|
||||
const formsDataItem: ChartData = { turn: turn.value };
|
||||
|
||||
// TODO: Dokończyć resztę DataItems'ów
|
||||
const statesDataItems: ChartData[] = [
|
||||
{ turn: turn.value },
|
||||
{ turn: turn.value },
|
||||
{ turn: turn.value },
|
||||
{ turn: turn.value },
|
||||
{ turn: turn.value }
|
||||
];
|
||||
|
||||
for (let j = 0; j < statesData.length; j++) {
|
||||
const state = statesData[j];
|
||||
const provincesDataItems: ChartData[] = [
|
||||
{ turn: turn.value },
|
||||
{ turn: turn.value },
|
||||
{ turn: turn.value },
|
||||
{ turn: turn.value }
|
||||
];
|
||||
|
||||
statesBurgsDataItem[state.name] = state.burgs;
|
||||
statesProvincesDataItem[state.name] = provincesData.filter(
|
||||
for (let i = 0; i < statesData.length; i++) {
|
||||
const state = statesData[i];
|
||||
|
||||
statesDataItems[0][state.name] = state.burgs;
|
||||
statesDataItems[1][state.name] = provincesData.filter(
|
||||
province => province.turn === turn.id && province.state === state.id
|
||||
).length;
|
||||
statesCellsDataItem[state.name] = state.cells;
|
||||
statesDataItems[2][state.name] = state.cells;
|
||||
statesDataItems[3][state.name] = state.ruralPopulation;
|
||||
statesDataItems[4][state.name] = state.urbanPopulation;
|
||||
}
|
||||
|
||||
dataForCharts.states.burgs.push(statesBurgsDataItem);
|
||||
dataForCharts.states.provinces.push(statesProvincesDataItem);
|
||||
dataForCharts.states.cells.push(statesCellsDataItem);
|
||||
dataForCharts.states.charts.burgs.push(statesDataItems[0]);
|
||||
dataForCharts.states.charts.provinces.push(statesDataItems[1]);
|
||||
dataForCharts.states.charts.cells.push(statesDataItems[2]);
|
||||
dataForCharts.states.charts.ruralPopulation.push(statesDataItems[3]);
|
||||
dataForCharts.states.charts.urbanPopulation.push(statesDataItems[4]);
|
||||
|
||||
for (let i = 0; i < provincesData.length; i++) {
|
||||
const province = provincesData[i];
|
||||
|
||||
provincesDataItems[0][province.name] = province.burgs;
|
||||
provincesDataItems[1][province.name] = province.cells;
|
||||
provincesDataItems[2][province.name] = province.ruralPopulation;
|
||||
provincesDataItems[3][province.name] = province.urbanPopulation;
|
||||
}
|
||||
|
||||
dataForCharts.provinces.charts.burgs.push(provincesDataItems[0]);
|
||||
dataForCharts.provinces.charts.cells.push(provincesDataItems[1]);
|
||||
dataForCharts.provinces.charts.ruralPopulation.push(provincesDataItems[2]);
|
||||
dataForCharts.provinces.charts.urbanPopulation.push(provincesDataItems[3]);
|
||||
}
|
||||
|
||||
console.log(dataForCharts);
|
||||
|
||||
// console.log(provincesData);
|
||||
|
||||
// console.table(statesData);
|
||||
// console.table(provincesData);
|
||||
// console.table(burgsData);
|
||||
// console.table(culturesData);
|
||||
// console.table(religionsData);
|
||||
|
||||
// console.log(statesData);
|
||||
|
||||
// TODO: dodać wykresy z shadcn-vue https://www.shadcn-vue.com/docs/charts.html
|
||||
|
||||
// TODO: Statystyki państw na przestrzeni tur, kolor z pola color:
|
||||
// - ilość miast - liniowy,
|
||||
// - ilość prowincji - liniowy,
|
||||
// - ilość kratek - liniowy,
|
||||
// - ilość kratek danej kultury - słupkowy,
|
||||
// - ilość kratek danej religii - słupkowy,
|
||||
// - ilość kratek danego biomu - słupkowy,z
|
||||
// - ilość populacji wiejskiej - liniowy,
|
||||
// - ilość populacji miejskiej - liniowy,
|
||||
// - ilość danych form rządu - liniowy
|
||||
|
||||
// TODO: Statystyki prowincji na przestrzeni tur, kolor z pola color:
|
||||
// - ilość miast - liniowy,
|
||||
// - ilość kratek - liniowy,
|
||||
// - ilość populacji wiejskiej - liniowy,
|
||||
// - ilość populacji miejskiej - liniowy,
|
||||
// - ilość danych form rządu - liniowy
|
||||
|
||||
// TODO: Statystyki miast na przestrzeni tur, kolor z pola color:
|
||||
// - ilość populacji - liniowy,
|
||||
// - ilość religii - liniowy,
|
||||
@@ -224,44 +164,134 @@ console.log(dataForCharts);
|
||||
// - ilość danych typów religii - liniowy,
|
||||
// - ilość danych form religii - liniowy,
|
||||
|
||||
const tabs: { [key: string]: string } = {
|
||||
states: 'Państwa',
|
||||
provinces: 'Prowincje',
|
||||
burgs: 'Miasta',
|
||||
cultures: 'Kultury',
|
||||
religions: 'Religie'
|
||||
};
|
||||
const tabs: {
|
||||
name: string;
|
||||
label: string;
|
||||
description: string;
|
||||
props: {
|
||||
config: Config;
|
||||
labels: string[];
|
||||
charts: Record<string, ChartData[]>;
|
||||
};
|
||||
}[] = [
|
||||
{
|
||||
name: 'states',
|
||||
label: 'Państwa',
|
||||
description: 'Statystyki państw',
|
||||
props: {
|
||||
config: dataForCharts.states.config,
|
||||
labels: [
|
||||
'Ilość miast',
|
||||
'Ilość prowincji',
|
||||
'Ilość kratek',
|
||||
'Ilość populacji wiejskiej ',
|
||||
'Ilość populacji miejskiej'
|
||||
],
|
||||
charts: dataForCharts.states.charts
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'provinces',
|
||||
label: 'Prowincje',
|
||||
description: 'Statystyki prowincji',
|
||||
props: {
|
||||
config: dataForCharts.provinces.config,
|
||||
labels: [
|
||||
'Ilość miast',
|
||||
'Ilość kratek',
|
||||
'Ilość populacji wiejskiej ',
|
||||
'Ilość populacji miejskiej'
|
||||
],
|
||||
charts: dataForCharts.provinces.charts
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'burgs',
|
||||
label: 'Miasta',
|
||||
description: 'Statystyki miast',
|
||||
props: {
|
||||
config: dataForCharts.burgs.config,
|
||||
charts: dataForCharts.burgs.charts
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'cultures',
|
||||
label: 'Kultury',
|
||||
description: 'Statystyki kultur',
|
||||
props: {
|
||||
config: dataForCharts.cultures.config,
|
||||
charts: dataForCharts.cultures.charts
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'religions',
|
||||
label: 'Religie',
|
||||
description: 'Statystyki religii',
|
||||
props: {
|
||||
config: dataForCharts.religions.config,
|
||||
charts: dataForCharts.religions.charts
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
console.log(tabs);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mt-12 flex h-screen items-center justify-center">
|
||||
<Tabs
|
||||
class="flex w-full flex-col items-center justify-center"
|
||||
:default-value="tabs[Object.keys(tabs)[0]]"
|
||||
>
|
||||
<Tabs class="flex w-full flex-col items-center justify-center" :default-value="tabs[0].name">
|
||||
<TabsList class="w-full items-center justify-center">
|
||||
<TabsTrigger v-for="(tab, key) in tabs" :key="key" :value="tab"> {{ tab }}</TabsTrigger>
|
||||
<TabsTrigger v-for="tab in tabs" :key="tab.name" :value="tab.name">
|
||||
{{ tab.label }}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent
|
||||
v-for="(tab, key) in tabs"
|
||||
:key="key"
|
||||
:value="tab"
|
||||
v-for="tab in tabs"
|
||||
:key="tab.name"
|
||||
:value="tab.name"
|
||||
class="h-screen w-full flex-col items-center justify-center"
|
||||
>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
{{ tab }}
|
||||
<!-- {{ props.title }} Numer <span class="text-primary">{{ turn.value }}</span> -->
|
||||
{{ tab.label }}
|
||||
</CardTitle>
|
||||
|
||||
<CardDescription> Jeżyk </CardDescription>
|
||||
<CardDescription class="flex flex-col">
|
||||
{{ tab.description }}
|
||||
|
||||
<Label class="mb-2 mt-5"> Jakiego tooltip'a użyć? </Label>
|
||||
|
||||
<div>
|
||||
<RadioGroup default-value="option-one">
|
||||
<div class="flex items-center space-x-2">
|
||||
<RadioGroupItem id="option-one" value="option-one" />
|
||||
<Label for="option-one">Klasycznego</Label>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<RadioGroupItem id="option-two" value="option-two" />
|
||||
<Label for="option-two">Uproszczonego</Label>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<RadioGroupItem id="option-three" value="option-three" />
|
||||
<Label for="option-three">Najlepsi i najgorsi</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<Separator />
|
||||
|
||||
<CardContent class="space-y-2 py-6"> </CardContent>
|
||||
<CardContent class="space-y-2 py-6">
|
||||
<!-- <component :is="tab.component" v-bind="tab.props" /> -->
|
||||
<ChartComponent
|
||||
:config="tab.props.config"
|
||||
:charts="tab.props.charts"
|
||||
:labels="tab.props.labels"
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
BIN
src/public/favicon.ico
Normal file
BIN
src/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 137 KiB |
@@ -1,6 +1,6 @@
|
||||
const ONE_HOUR = 60 * 60 * 1000; // 1 godzina w milisekundach
|
||||
// TODO: Napisać unit testy dla useChartsAndStatsStore
|
||||
export const useChartsAndStatsStore = defineStore('useChartsAndStatsStore', () => {
|
||||
// TODO: Napisać unit testy dla cacheFullListResponses
|
||||
export const cacheFullListResponses = defineStore('cacheFullListResponses', () => {
|
||||
const pb = usePocketBase();
|
||||
|
||||
const turnsData = ref(null);
|
||||
@@ -20,7 +20,7 @@ export const useChartsAndStatsStore = defineStore('useChartsAndStatsStore', () =
|
||||
|
||||
const fetchStatesData = async () => {
|
||||
if (statesData.value && isCached('statesData')) return statesData.value;
|
||||
const data = await pb.collection('states').getFullList({ expand: 'turn' });
|
||||
const data = await pb.collection('states').getFullList();
|
||||
statesData.value = data;
|
||||
cacheData('statesData', data);
|
||||
return data;
|
||||
@@ -28,7 +28,7 @@ export const useChartsAndStatsStore = defineStore('useChartsAndStatsStore', () =
|
||||
|
||||
const fetchProvincesData = async () => {
|
||||
if (provincesData.value && isCached('provincesData')) return provincesData.value;
|
||||
const data = await pb.collection('provinces').getFullList({ expand: 'turn' });
|
||||
const data = await pb.collection('provinces').getFullList();
|
||||
provincesData.value = data;
|
||||
cacheData('provincesData', data);
|
||||
return data;
|
||||
@@ -36,7 +36,7 @@ export const useChartsAndStatsStore = defineStore('useChartsAndStatsStore', () =
|
||||
|
||||
const fetchBurgsData = async () => {
|
||||
if (burgsData.value && isCached('burgsData')) return burgsData.value;
|
||||
const data = await pb.collection('burgs').getFullList({ expand: 'turn' });
|
||||
const data = await pb.collection('burgs').getFullList();
|
||||
burgsData.value = data;
|
||||
cacheData('burgsData', data);
|
||||
return data;
|
||||
@@ -44,7 +44,7 @@ export const useChartsAndStatsStore = defineStore('useChartsAndStatsStore', () =
|
||||
|
||||
const fetchCulturesData = async () => {
|
||||
if (culturesData.value && isCached('culturesData')) return culturesData.value;
|
||||
const data = await pb.collection('cultures').getFullList({ expand: 'turn' });
|
||||
const data = await pb.collection('cultures').getFullList();
|
||||
culturesData.value = data;
|
||||
cacheData('culturesData', data);
|
||||
return data;
|
||||
@@ -52,7 +52,7 @@ export const useChartsAndStatsStore = defineStore('useChartsAndStatsStore', () =
|
||||
|
||||
const fetchReligionsData = async () => {
|
||||
if (religionsData.value && isCached('religionsData')) return religionsData.value;
|
||||
const data = await pb.collection('religions').getFullList({ expand: 'turn' });
|
||||
const data = await pb.collection('religions').getFullList();
|
||||
religionsData.value = data;
|
||||
cacheData('religionsData', data);
|
||||
return data;
|
||||
@@ -70,12 +70,12 @@ export const useChartsAndStatsStore = defineStore('useChartsAndStatsStore', () =
|
||||
};
|
||||
|
||||
return {
|
||||
turnsData,
|
||||
statesData,
|
||||
provincesData,
|
||||
burgsData,
|
||||
culturesData,
|
||||
religionsData,
|
||||
// turnsData,
|
||||
// statesData,
|
||||
// provincesData,
|
||||
// burgsData,
|
||||
// culturesData,
|
||||
// religionsData,
|
||||
fetchTurnsData,
|
||||
fetchStatesData,
|
||||
fetchProvincesData,
|
||||
18
src/types/auto-imports.d.ts
vendored
18
src/types/auto-imports.d.ts
vendored
@@ -6,7 +6,7 @@
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
const BarChart: typeof import('../components/ui/chart-bar/index')['BarChart']
|
||||
const BarChart: (typeof import('../components/ui/chart-bar/index'))['BarChart']
|
||||
const Button: typeof import('../components/ui/button/index')['Button']
|
||||
const Card: typeof import('../components/ui/card/index')['Card']
|
||||
const CardContent: typeof import('../components/ui/card/index')['CardContent']
|
||||
@@ -70,12 +70,13 @@ declare global {
|
||||
const PopoverTrigger: typeof import('../components/ui/popover/index')['PopoverTrigger']
|
||||
const RadioGroup: typeof import('../components/ui/radio-group/index')['RadioGroup']
|
||||
const RadioGroupItem: typeof import('../components/ui/radio-group/index')['RadioGroupItem']
|
||||
const ResizableHandle: typeof import('../components/ui/resizable/index')['ResizableHandle']
|
||||
const ResizablePanel: typeof import('../components/ui/resizable/index')['ResizablePanel']
|
||||
const ResizablePanelGroup: typeof import('../components/ui/resizable/index')['ResizablePanelGroup']
|
||||
const ResizableHandle: (typeof import('../components/ui/resizable/index'))['ResizableHandle']
|
||||
const ResizablePanel: (typeof import('../components/ui/resizable/index'))['ResizablePanel']
|
||||
const ResizablePanelGroup: (typeof import('../components/ui/resizable/index'))['ResizablePanelGroup']
|
||||
const ScrollArea: typeof import('../components/ui/scroll-area/index')['ScrollArea']
|
||||
const ScrollBar: typeof import('../components/ui/scroll-area/index')['ScrollBar']
|
||||
const Separator: typeof import('../components/ui/separator/index')['Separator']
|
||||
const Switch: typeof import('../components/ui/switch/index')['Switch']
|
||||
const Tabs: typeof import('../components/ui/tabs/index')['Tabs']
|
||||
const TabsContent: typeof import('../components/ui/tabs/index')['TabsContent']
|
||||
const TabsList: typeof import('../components/ui/tabs/index')['TabsList']
|
||||
@@ -97,8 +98,9 @@ declare global {
|
||||
const beforeAll: typeof import('vitest')['beforeAll']
|
||||
const beforeEach: typeof import('vitest')['beforeEach']
|
||||
const buttonVariants: typeof import('../components/ui/button/index')['buttonVariants']
|
||||
const cacheFullListResponses: typeof import('../stores/useCacheFullListResponsesStore')['cacheFullListResponses']
|
||||
const chai: typeof import('vitest')['chai']
|
||||
const chartsAndStatsStore: typeof import('../stores/chartsAndStatsStore')['chartsAndStatsStore']
|
||||
const chartsAndStatsStore: (typeof import('../stores/useCacheFullListResponsesStore'))['chartsAndStatsStore']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const computedAsync: typeof import('@vueuse/core')['computedAsync']
|
||||
const computedEager: typeof import('@vueuse/core')['computedEager']
|
||||
@@ -246,9 +248,9 @@ declare global {
|
||||
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
|
||||
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
|
||||
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
|
||||
const useCacheStore: typeof import('../stores/chartsAndStatsStore')['useCacheStore']
|
||||
const useCacheStore: (typeof import('../stores/useCacheFullListResponsesStore'))['useCacheStore']
|
||||
const useCached: typeof import('@vueuse/core')['useCached']
|
||||
const useChartsAndStatsStore: typeof import('../stores/chartsAndStatsStore')['useChartsAndStatsStore']
|
||||
const useChartsAndStatsStore: (typeof import('../stores/useCacheFullListResponsesStore'))['useChartsAndStatsStore']
|
||||
const useClipboard: typeof import('@vueuse/core')['useClipboard']
|
||||
const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems']
|
||||
const useCloned: typeof import('@vueuse/core')['useCloned']
|
||||
@@ -261,7 +263,7 @@ declare global {
|
||||
const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement']
|
||||
const useCycleList: typeof import('@vueuse/core')['useCycleList']
|
||||
const useDark: typeof import('@vueuse/core')['useDark']
|
||||
const useDataStore: typeof import('../stores/chartsAndStatsStore')['useDataStore']
|
||||
const useDataStore: (typeof import('../stores/useCacheFullListResponsesStore'))['useDataStore']
|
||||
const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
|
||||
const useDebounce: typeof import('@vueuse/core')['useDebounce']
|
||||
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
|
||||
|
||||
66
src/types/chartsTypes.ts
Normal file
66
src/types/chartsTypes.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
interface DataForCharts {
|
||||
states: {
|
||||
config: Config;
|
||||
charts: {
|
||||
burgs: ChartData[];
|
||||
provinces: ChartData[];
|
||||
cells: ChartData[];
|
||||
ruralPopulation: ChartData[];
|
||||
urbanPopulation: ChartData[];
|
||||
};
|
||||
};
|
||||
provinces: {
|
||||
config: Config;
|
||||
charts: {
|
||||
burgs: ChartData[];
|
||||
cells: ChartData[];
|
||||
ruralPopulation: ChartData[];
|
||||
urbanPopulation: ChartData[];
|
||||
};
|
||||
};
|
||||
burgs: {
|
||||
config: Config;
|
||||
charts: {
|
||||
population: ChartData[];
|
||||
religions: ChartData[];
|
||||
cultures: ChartData[];
|
||||
capitals: ChartData[];
|
||||
ports: ChartData[];
|
||||
cities: ChartData[];
|
||||
walls: ChartData[];
|
||||
plazas: ChartData[];
|
||||
temples: ChartData[];
|
||||
shantyTowns: ChartData[];
|
||||
};
|
||||
};
|
||||
cultures: {
|
||||
config: Config;
|
||||
charts: {
|
||||
cells: ChartData[];
|
||||
population: ChartData[];
|
||||
types: ChartData[];
|
||||
namesbases: ChartData[];
|
||||
};
|
||||
};
|
||||
religions: {
|
||||
config: Config;
|
||||
charts: {
|
||||
cells: ChartData[];
|
||||
population: ChartData[];
|
||||
types: ChartData[];
|
||||
forms: ChartData[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
interface ChartData {
|
||||
turn: number;
|
||||
[key: string]: number;
|
||||
}
|
||||
|
||||
interface Config {
|
||||
categories: string[];
|
||||
colors?: string[];
|
||||
}
|
||||
|
||||
export type { ChartData, Config, DataForCharts };
|
||||
5
src/types/components.d.ts
vendored
5
src/types/components.d.ts
vendored
@@ -16,6 +16,8 @@ declare module 'vue' {
|
||||
CardFooter: typeof import('./../components/ui/card/CardFooter.vue')['default']
|
||||
CardHeader: typeof import('./../components/ui/card/CardHeader.vue')['default']
|
||||
CardTitle: typeof import('./../components/ui/card/CardTitle.vue')['default']
|
||||
Chart: typeof import('../components/charts-and-stats/chartComponent.vue')['default']
|
||||
ChartComponent: typeof import('./../components/charts-and-stats/chartComponent.vue')['default']
|
||||
ChartCrosshair: typeof import('./../components/ui/chart/ChartCrosshair.vue')['default']
|
||||
ChartLegend: typeof import('./../components/ui/chart/ChartLegend.vue')['default']
|
||||
ChartSingleTooltip: typeof import('./../components/ui/chart/ChartSingleTooltip.vue')['default']
|
||||
@@ -106,7 +108,8 @@ declare module 'vue' {
|
||||
SidebarRail: typeof import('./../components/ui/sidebar/SidebarRail.vue')['default']
|
||||
SidebarSeparator: typeof import('./../components/ui/sidebar/SidebarSeparator.vue')['default']
|
||||
SidebarTrigger: typeof import('./../components/ui/sidebar/SidebarTrigger.vue')['default']
|
||||
StatesCharts: typeof import('./../components/charts-and-stats/statesCharts.vue')['default']
|
||||
StatesCharts: typeof import('../components/charts-and-stats/chartComponent.vue')['default']
|
||||
Switch: typeof import('./../components/ui/switch/Switch.vue')['default']
|
||||
Tabs: typeof import('./../components/ui/tabs/Tabs.vue')['default']
|
||||
TabsContent: typeof import('./../components/ui/tabs/TabsContent.vue')['default']
|
||||
TabsList: typeof import('./../components/ui/tabs/TabsList.vue')['default']
|
||||
|
||||
@@ -1,376 +1,393 @@
|
||||
/**
|
||||
* This file was @generated using pocketbase-typegen
|
||||
*/
|
||||
* This file was @generated using pocketbase-typegen
|
||||
*/
|
||||
|
||||
import type PocketBase from 'pocketbase'
|
||||
import type { RecordService } from 'pocketbase'
|
||||
import type PocketBase from 'pocketbase';
|
||||
import type { RecordService } from 'pocketbase';
|
||||
|
||||
export enum Collections {
|
||||
Burgs = "burgs",
|
||||
Cultures = "cultures",
|
||||
Maps = "maps",
|
||||
Provinces = "provinces",
|
||||
Religions = "religions",
|
||||
ReportInputs = "reportInputs",
|
||||
ReportOutputs = "reportOutputs",
|
||||
Reports = "reports",
|
||||
States = "states",
|
||||
Turns = "turns",
|
||||
Users = "users",
|
||||
Burgs = 'burgs',
|
||||
Cultures = 'cultures',
|
||||
Maps = 'maps',
|
||||
Provinces = 'provinces',
|
||||
Religions = 'religions',
|
||||
ReportInputs = 'reportInputs',
|
||||
ReportOutputs = 'reportOutputs',
|
||||
Reports = 'reports',
|
||||
States = 'states',
|
||||
Turns = 'turns',
|
||||
Users = 'users'
|
||||
}
|
||||
|
||||
// Alias types for improved usability
|
||||
export type IsoDateString = string
|
||||
export type RecordIdString = string
|
||||
export type HTMLString = string
|
||||
export type IsoDateString = string;
|
||||
export type RecordIdString = string;
|
||||
export type HTMLString = string;
|
||||
|
||||
// System fields
|
||||
export type BaseSystemFields<T = never> = {
|
||||
id: RecordIdString
|
||||
created: IsoDateString
|
||||
updated: IsoDateString
|
||||
collectionId: string
|
||||
collectionName: Collections
|
||||
expand?: T
|
||||
}
|
||||
id: RecordIdString;
|
||||
created: IsoDateString;
|
||||
updated: IsoDateString;
|
||||
collectionId: string;
|
||||
collectionName: Collections;
|
||||
expand?: T;
|
||||
};
|
||||
|
||||
export type AuthSystemFields<T = never> = {
|
||||
email: string
|
||||
emailVisibility: boolean
|
||||
username: string
|
||||
verified: boolean
|
||||
} & BaseSystemFields<T>
|
||||
email: string;
|
||||
emailVisibility: boolean;
|
||||
username: string;
|
||||
verified: boolean;
|
||||
} & BaseSystemFields<T>;
|
||||
|
||||
// Record types for each collection
|
||||
|
||||
export type BurgsRecord<Temblem = unknown> = {
|
||||
cityGeneratorLink: string
|
||||
culture: RecordIdString
|
||||
emblem: null | Temblem
|
||||
isCapital?: boolean
|
||||
isCitadel?: boolean
|
||||
isPlaza?: boolean
|
||||
isPort?: boolean
|
||||
isShantyTown?: boolean
|
||||
isTemple?: boolean
|
||||
isWalls?: boolean
|
||||
name: string
|
||||
population?: number
|
||||
province?: RecordIdString
|
||||
religion: RecordIdString
|
||||
state: RecordIdString
|
||||
turn: RecordIdString
|
||||
}
|
||||
cityGeneratorLink: string;
|
||||
culture: RecordIdString;
|
||||
emblem: null | Temblem;
|
||||
isCapital?: boolean;
|
||||
isCitadel?: boolean;
|
||||
isPlaza?: boolean;
|
||||
isPort?: boolean;
|
||||
isShantyTown?: boolean;
|
||||
isTemple?: boolean;
|
||||
isWalls?: boolean;
|
||||
name: string;
|
||||
population?: number;
|
||||
province?: RecordIdString;
|
||||
religion: RecordIdString;
|
||||
state: RecordIdString;
|
||||
turn: RecordIdString;
|
||||
};
|
||||
|
||||
export enum CulturesTypeOptions {
|
||||
"Generic" = "Generic",
|
||||
"River" = "River",
|
||||
"Lake" = "Lake",
|
||||
"Naval" = "Naval",
|
||||
"Nomadic" = "Nomadic",
|
||||
"Hunting" = "Hunting",
|
||||
"Highland" = "Highland",
|
||||
'Generic' = 'Generic',
|
||||
'River' = 'River',
|
||||
'Lake' = 'Lake',
|
||||
'Naval' = 'Naval',
|
||||
'Nomadic' = 'Nomadic',
|
||||
'Hunting' = 'Hunting',
|
||||
'Highland' = 'Highland'
|
||||
}
|
||||
|
||||
export enum CulturesNamesbaseOptions {
|
||||
"German" = "German",
|
||||
"English" = "English",
|
||||
"French" = "French",
|
||||
"Italian" = "Italian",
|
||||
"Castillian" = "Castillian",
|
||||
"Ruthenian" = "Ruthenian",
|
||||
"Nordic" = "Nordic",
|
||||
"Greek" = "Greek",
|
||||
"Roman" = "Roman",
|
||||
"Finnic" = "Finnic",
|
||||
"Korean" = "Korean",
|
||||
"Chinese" = "Chinese",
|
||||
"Japanese" = "Japanese",
|
||||
"Portuguese" = "Portuguese",
|
||||
"Nahuatl" = "Nahuatl",
|
||||
"Hungarian" = "Hungarian",
|
||||
"Turkish" = "Turkish",
|
||||
"Berber" = "Berber",
|
||||
"Arabic" = "Arabic",
|
||||
"Inuit" = "Inuit",
|
||||
"Basque" = "Basque",
|
||||
"Nigerian" = "Nigerian",
|
||||
"Celtic" = "Celtic",
|
||||
"Mesopotamian" = "Mesopotamian",
|
||||
"Iranian" = "Iranian",
|
||||
"Hawaiian" = "Hawaiian",
|
||||
"Karnataka" = "Karnataka",
|
||||
"Quechua" = "Quechua",
|
||||
"Swahili" = "Swahili",
|
||||
"Vietnamese" = "Vietnamese",
|
||||
"Cantonese" = "Cantonese",
|
||||
"Mongolian" = "Mongolian",
|
||||
"Human Generic" = "Human Generic",
|
||||
"Elven" = "Elven",
|
||||
"Dark Elven" = "Dark Elven",
|
||||
"Dwarven" = "Dwarven",
|
||||
"Goblin" = "Goblin",
|
||||
"Orc" = "Orc",
|
||||
"Giant" = "Giant",
|
||||
"Draconic" = "Draconic",
|
||||
"Arachnid" = "Arachnid",
|
||||
"Serpents" = "Serpents",
|
||||
"Levantine" = "Levantine",
|
||||
'German' = 'German',
|
||||
'English' = 'English',
|
||||
'French' = 'French',
|
||||
'Italian' = 'Italian',
|
||||
'Castillian' = 'Castillian',
|
||||
'Ruthenian' = 'Ruthenian',
|
||||
'Nordic' = 'Nordic',
|
||||
'Greek' = 'Greek',
|
||||
'Roman' = 'Roman',
|
||||
'Finnic' = 'Finnic',
|
||||
'Korean' = 'Korean',
|
||||
'Chinese' = 'Chinese',
|
||||
'Japanese' = 'Japanese',
|
||||
'Portuguese' = 'Portuguese',
|
||||
'Nahuatl' = 'Nahuatl',
|
||||
'Hungarian' = 'Hungarian',
|
||||
'Turkish' = 'Turkish',
|
||||
'Berber' = 'Berber',
|
||||
'Arabic' = 'Arabic',
|
||||
'Inuit' = 'Inuit',
|
||||
'Basque' = 'Basque',
|
||||
'Nigerian' = 'Nigerian',
|
||||
'Celtic' = 'Celtic',
|
||||
'Mesopotamian' = 'Mesopotamian',
|
||||
'Iranian' = 'Iranian',
|
||||
'Hawaiian' = 'Hawaiian',
|
||||
'Karnataka' = 'Karnataka',
|
||||
'Quechua' = 'Quechua',
|
||||
'Swahili' = 'Swahili',
|
||||
'Vietnamese' = 'Vietnamese',
|
||||
'Cantonese' = 'Cantonese',
|
||||
'Mongolian' = 'Mongolian',
|
||||
'Human Generic' = 'Human Generic',
|
||||
'Elven' = 'Elven',
|
||||
'Dark Elven' = 'Dark Elven',
|
||||
'Dwarven' = 'Dwarven',
|
||||
'Goblin' = 'Goblin',
|
||||
'Orc' = 'Orc',
|
||||
'Giant' = 'Giant',
|
||||
'Draconic' = 'Draconic',
|
||||
'Arachnid' = 'Arachnid',
|
||||
'Serpents' = 'Serpents',
|
||||
'Levantine' = 'Levantine'
|
||||
}
|
||||
export type CulturesRecord = {
|
||||
cells?: number
|
||||
color?: string
|
||||
name: string
|
||||
namesbase: CulturesNamesbaseOptions
|
||||
population?: number
|
||||
turn: RecordIdString
|
||||
type?: CulturesTypeOptions
|
||||
}
|
||||
cells?: number;
|
||||
color?: string;
|
||||
name: string;
|
||||
namesbase: CulturesNamesbaseOptions;
|
||||
population?: number;
|
||||
turn: RecordIdString;
|
||||
type?: CulturesTypeOptions;
|
||||
};
|
||||
|
||||
export type MapsRecord = {
|
||||
file: string
|
||||
name: string
|
||||
turn?: RecordIdString
|
||||
}
|
||||
file: string;
|
||||
name: string;
|
||||
turn?: RecordIdString;
|
||||
};
|
||||
|
||||
export enum ProvincesFormOptions {
|
||||
"Area" = "Area",
|
||||
"Autonomy" = "Autonomy",
|
||||
"Barony" = "Barony",
|
||||
"Canton" = "Canton",
|
||||
"Captaincy" = "Captaincy",
|
||||
"Chiefdom" = "Chiefdom",
|
||||
"Clan" = "Clan",
|
||||
"Colony" = "Colony",
|
||||
"Council" = "Council",
|
||||
"County" = "County",
|
||||
"Deanery" = "Deanery",
|
||||
"Department" = "Department",
|
||||
"Dependency" = "Dependency",
|
||||
"Diaconate" = "Diaconate",
|
||||
"District" = "District",
|
||||
"Earldom" = "Earldom",
|
||||
"Governorate" = "Governorate",
|
||||
"Island" = "Island",
|
||||
"Islands" = "Islands",
|
||||
"Land" = "Land",
|
||||
"Landgrave" = "Landgrave",
|
||||
"Mandate" = "Mandate",
|
||||
"Margrave" = "Margrave",
|
||||
"Municipality" = "Municipality",
|
||||
"Occupation zone" = "Occupation zone",
|
||||
"Parish" = "Parish",
|
||||
"Prefecture" = "Prefecture",
|
||||
"Province" = "Province",
|
||||
"Region" = "Region",
|
||||
"Republic" = "Republic",
|
||||
"Reservation" = "Reservation",
|
||||
"Seneschalty" = "Seneschalty",
|
||||
"Shire" = "Shire",
|
||||
"State" = "State",
|
||||
"Territory" = "Territory",
|
||||
"Tribe" = "Tribe",
|
||||
'Area' = 'Area',
|
||||
'Autonomy' = 'Autonomy',
|
||||
'Barony' = 'Barony',
|
||||
'Canton' = 'Canton',
|
||||
'Captaincy' = 'Captaincy',
|
||||
'Chiefdom' = 'Chiefdom',
|
||||
'Clan' = 'Clan',
|
||||
'Colony' = 'Colony',
|
||||
'Council' = 'Council',
|
||||
'County' = 'County',
|
||||
'Deanery' = 'Deanery',
|
||||
'Department' = 'Department',
|
||||
'Dependency' = 'Dependency',
|
||||
'Diaconate' = 'Diaconate',
|
||||
'District' = 'District',
|
||||
'Earldom' = 'Earldom',
|
||||
'Governorate' = 'Governorate',
|
||||
'Island' = 'Island',
|
||||
'Islands' = 'Islands',
|
||||
'Land' = 'Land',
|
||||
'Landgrave' = 'Landgrave',
|
||||
'Mandate' = 'Mandate',
|
||||
'Margrave' = 'Margrave',
|
||||
'Municipality' = 'Municipality',
|
||||
'Occupation zone' = 'Occupation zone',
|
||||
'Parish' = 'Parish',
|
||||
'Prefecture' = 'Prefecture',
|
||||
'Province' = 'Province',
|
||||
'Region' = 'Region',
|
||||
'Republic' = 'Republic',
|
||||
'Reservation' = 'Reservation',
|
||||
'Seneschalty' = 'Seneschalty',
|
||||
'Shire' = 'Shire',
|
||||
'State' = 'State',
|
||||
'Territory' = 'Territory',
|
||||
'Tribe' = 'Tribe'
|
||||
}
|
||||
export type ProvincesRecord = {
|
||||
burgs?: number
|
||||
capital?: string
|
||||
cells?: number
|
||||
color: string
|
||||
form: ProvincesFormOptions
|
||||
name: string
|
||||
nameFull: string
|
||||
ruralPopulation?: number
|
||||
state: RecordIdString
|
||||
turn: RecordIdString
|
||||
urbanPopulation?: number
|
||||
}
|
||||
burgs?: number;
|
||||
capital?: string;
|
||||
cells?: number;
|
||||
color: string;
|
||||
form: ProvincesFormOptions;
|
||||
name: string;
|
||||
nameFull: string;
|
||||
ruralPopulation?: number;
|
||||
state: RecordIdString;
|
||||
turn: RecordIdString;
|
||||
urbanPopulation?: number;
|
||||
};
|
||||
|
||||
export enum ReligionsTypeOptions {
|
||||
"Organized" = "Organized",
|
||||
"Heresy" = "Heresy",
|
||||
"Cult" = "Cult",
|
||||
"Folk" = "Folk",
|
||||
'Organized' = 'Organized',
|
||||
'Heresy' = 'Heresy',
|
||||
'Cult' = 'Cult',
|
||||
'Folk' = 'Folk'
|
||||
}
|
||||
export type ReligionsRecord = {
|
||||
cells?: number
|
||||
color?: string
|
||||
form?: string
|
||||
name: string
|
||||
population?: number
|
||||
supremeDeity?: string
|
||||
turn: RecordIdString
|
||||
type?: ReligionsTypeOptions
|
||||
}
|
||||
cells?: number;
|
||||
color?: string;
|
||||
form?: string;
|
||||
name: string;
|
||||
population?: number;
|
||||
supremeDeity?: string;
|
||||
turn: RecordIdString;
|
||||
type?: ReligionsTypeOptions;
|
||||
};
|
||||
|
||||
export type ReportInputsRecord = {
|
||||
sdad?: string
|
||||
}
|
||||
sdad?: string;
|
||||
};
|
||||
|
||||
export type ReportOutputsRecord = {
|
||||
sadasds?: string
|
||||
}
|
||||
sadasds?: string;
|
||||
};
|
||||
|
||||
export type ReportsRecord = {
|
||||
reportInput: RecordIdString
|
||||
reportOutput: RecordIdString
|
||||
state: RecordIdString
|
||||
turn: RecordIdString
|
||||
}
|
||||
reportInput: RecordIdString;
|
||||
reportOutput: RecordIdString;
|
||||
state: RecordIdString;
|
||||
turn: RecordIdString;
|
||||
};
|
||||
|
||||
export enum StatesFormOptions {
|
||||
"Beylik" = "Beylik",
|
||||
"Despotate" = "Despotate",
|
||||
"Dominion" = "Dominion",
|
||||
"Duchy" = "Duchy",
|
||||
"Emirate" = "Emirate",
|
||||
"Empire" = "Empire",
|
||||
"Horde" = "Horde",
|
||||
"Grand Duchy" = "Grand Duchy",
|
||||
"Heptarchy" = "Heptarchy",
|
||||
"Khaganate" = "Khaganate",
|
||||
"Khanate" = "Khanate",
|
||||
"Kingdom" = "Kingdom",
|
||||
"Marches" = "Marches",
|
||||
"Principality" = "Principality",
|
||||
"Satrapy" = "Satrapy",
|
||||
"Shogunate" = "Shogunate",
|
||||
"Sultanate" = "Sultanate",
|
||||
"Tsardom" = "Tsardom",
|
||||
"Ulus" = "Ulus",
|
||||
"Viceroyalty" = "Viceroyalty",
|
||||
"Chancellery" = "Chancellery",
|
||||
"City-state" = "City-state",
|
||||
"Diarchy" = "Diarchy",
|
||||
"Federation" = "Federation",
|
||||
"Free City" = "Free City",
|
||||
"Most Serene Republic" = "Most Serene Republic",
|
||||
"Oligarchy" = "Oligarchy",
|
||||
"Protectorate" = "Protectorate",
|
||||
"Republic" = "Republic",
|
||||
"Tetrarchy" = "Tetrarchy",
|
||||
"Trade Company" = "Trade Company",
|
||||
"Triumvirate" = "Triumvirate",
|
||||
"Confederacy" = "Confederacy",
|
||||
"Confederation" = "Confederation",
|
||||
"Conglomerate" = "Conglomerate",
|
||||
"Commonwealth" = "Commonwealth",
|
||||
"League" = "League",
|
||||
"Union" = "Union",
|
||||
"United Hordes" = "United Hordes",
|
||||
"United Kingdom" = "United Kingdom",
|
||||
"United Provinces" = "United Provinces",
|
||||
"United Republic" = "United Republic",
|
||||
"United States" = "United States",
|
||||
"United Tribes" = "United Tribes",
|
||||
"Bishopric" = "Bishopric",
|
||||
"Brotherhood" = "Brotherhood",
|
||||
"Caliphate" = "Caliphate",
|
||||
"Diocese" = "Diocese",
|
||||
"Divine Duchy" = "Divine Duchy",
|
||||
"Divine Grand Duchy" = "Divine Grand Duchy",
|
||||
"Divine Principality" = "Divine Principality",
|
||||
"Divine Kingdom" = "Divine Kingdom",
|
||||
"Divine Empire" = "Divine Empire",
|
||||
"Eparchy" = "Eparchy",
|
||||
"Exarchate" = "Exarchate",
|
||||
"Holy State" = "Holy State",
|
||||
"Imamah" = "Imamah",
|
||||
"Patriarchate" = "Patriarchate",
|
||||
"Theocracy" = "Theocracy",
|
||||
"Commune" = "Commune",
|
||||
"Community" = "Community",
|
||||
"Council" = "Council",
|
||||
"Free Territory" = "Free Territory",
|
||||
"Tribes" = "Tribes",
|
||||
}
|
||||
export type StatesRecord<TbiomesCells = unknown, TculturesCells = unknown, TreligionsCells = unknown> = {
|
||||
biomesCells?: null | TbiomesCells
|
||||
burgs?: number
|
||||
capital?: string
|
||||
cells?: number
|
||||
color?: string
|
||||
culture?: RecordIdString
|
||||
culturesCells?: null | TculturesCells
|
||||
form?: StatesFormOptions
|
||||
name: string
|
||||
nameFull?: string
|
||||
religionsCells?: null | TreligionsCells
|
||||
ruralPopulation?: number
|
||||
turn: RecordIdString
|
||||
urbanPopulation?: number
|
||||
user?: RecordIdString
|
||||
'Beylik' = 'Beylik',
|
||||
'Despotate' = 'Despotate',
|
||||
'Dominion' = 'Dominion',
|
||||
'Duchy' = 'Duchy',
|
||||
'Emirate' = 'Emirate',
|
||||
'Empire' = 'Empire',
|
||||
'Horde' = 'Horde',
|
||||
'Grand Duchy' = 'Grand Duchy',
|
||||
'Heptarchy' = 'Heptarchy',
|
||||
'Khaganate' = 'Khaganate',
|
||||
'Khanate' = 'Khanate',
|
||||
'Kingdom' = 'Kingdom',
|
||||
'Marches' = 'Marches',
|
||||
'Principality' = 'Principality',
|
||||
'Satrapy' = 'Satrapy',
|
||||
'Shogunate' = 'Shogunate',
|
||||
'Sultanate' = 'Sultanate',
|
||||
'Tsardom' = 'Tsardom',
|
||||
'Ulus' = 'Ulus',
|
||||
'Viceroyalty' = 'Viceroyalty',
|
||||
'Chancellery' = 'Chancellery',
|
||||
'City-state' = 'City-state',
|
||||
'Diarchy' = 'Diarchy',
|
||||
'Federation' = 'Federation',
|
||||
'Free City' = 'Free City',
|
||||
'Most Serene Republic' = 'Most Serene Republic',
|
||||
'Oligarchy' = 'Oligarchy',
|
||||
'Protectorate' = 'Protectorate',
|
||||
'Republic' = 'Republic',
|
||||
'Tetrarchy' = 'Tetrarchy',
|
||||
'Trade Company' = 'Trade Company',
|
||||
'Triumvirate' = 'Triumvirate',
|
||||
'Confederacy' = 'Confederacy',
|
||||
'Confederation' = 'Confederation',
|
||||
'Conglomerate' = 'Conglomerate',
|
||||
'Commonwealth' = 'Commonwealth',
|
||||
'League' = 'League',
|
||||
'Union' = 'Union',
|
||||
'United Hordes' = 'United Hordes',
|
||||
'United Kingdom' = 'United Kingdom',
|
||||
'United Provinces' = 'United Provinces',
|
||||
'United Republic' = 'United Republic',
|
||||
'United States' = 'United States',
|
||||
'United Tribes' = 'United Tribes',
|
||||
'Bishopric' = 'Bishopric',
|
||||
'Brotherhood' = 'Brotherhood',
|
||||
'Caliphate' = 'Caliphate',
|
||||
'Diocese' = 'Diocese',
|
||||
'Divine Duchy' = 'Divine Duchy',
|
||||
'Divine Grand Duchy' = 'Divine Grand Duchy',
|
||||
'Divine Principality' = 'Divine Principality',
|
||||
'Divine Kingdom' = 'Divine Kingdom',
|
||||
'Divine Empire' = 'Divine Empire',
|
||||
'Eparchy' = 'Eparchy',
|
||||
'Exarchate' = 'Exarchate',
|
||||
'Holy State' = 'Holy State',
|
||||
'Imamah' = 'Imamah',
|
||||
'Patriarchate' = 'Patriarchate',
|
||||
'Theocracy' = 'Theocracy',
|
||||
'Commune' = 'Commune',
|
||||
'Community' = 'Community',
|
||||
'Council' = 'Council',
|
||||
'Free Territory' = 'Free Territory',
|
||||
'Tribes' = 'Tribes'
|
||||
}
|
||||
export type StatesRecord<
|
||||
TbiomesCells = unknown,
|
||||
TculturesCells = unknown,
|
||||
TreligionsCells = unknown
|
||||
> = {
|
||||
biomesCells?: null | TbiomesCells;
|
||||
burgs?: number;
|
||||
capital?: string;
|
||||
cells?: number;
|
||||
color?: string;
|
||||
culture?: RecordIdString;
|
||||
culturesCells?: null | TculturesCells;
|
||||
form?: StatesFormOptions;
|
||||
name: string;
|
||||
nameFull?: string;
|
||||
religionsCells?: null | TreligionsCells;
|
||||
ruralPopulation?: number;
|
||||
turn: RecordIdString;
|
||||
urbanPopulation?: number;
|
||||
user?: RecordIdString;
|
||||
};
|
||||
|
||||
export type TurnsRecord = {
|
||||
value?: number
|
||||
}
|
||||
value?: number;
|
||||
};
|
||||
|
||||
export enum UsersRoleOptions {
|
||||
"user" = "user",
|
||||
"moderator" = "moderator",
|
||||
"admin" = "admin",
|
||||
'user' = 'user',
|
||||
'moderator' = 'moderator',
|
||||
'admin' = 'admin'
|
||||
}
|
||||
export type UsersRecord = {
|
||||
avatar?: string
|
||||
role: UsersRoleOptions
|
||||
}
|
||||
avatar?: string;
|
||||
role: UsersRoleOptions;
|
||||
};
|
||||
|
||||
// Response types include system fields and match responses from the PocketBase API
|
||||
export type BurgsResponse<Temblem = unknown, Texpand = unknown> = Required<BurgsRecord<Temblem>> & BaseSystemFields<Texpand>
|
||||
export type CulturesResponse<Texpand = unknown> = Required<CulturesRecord> & BaseSystemFields<Texpand>
|
||||
export type MapsResponse<Texpand = unknown> = Required<MapsRecord> & BaseSystemFields<Texpand>
|
||||
export type ProvincesResponse<Texpand = unknown> = Required<ProvincesRecord> & BaseSystemFields<Texpand>
|
||||
export type ReligionsResponse<Texpand = unknown> = Required<ReligionsRecord> & BaseSystemFields<Texpand>
|
||||
export type ReportInputsResponse<Texpand = unknown> = Required<ReportInputsRecord> & BaseSystemFields<Texpand>
|
||||
export type ReportOutputsResponse<Texpand = unknown> = Required<ReportOutputsRecord> & BaseSystemFields<Texpand>
|
||||
export type ReportsResponse<Texpand = unknown> = Required<ReportsRecord> & BaseSystemFields<Texpand>
|
||||
export type StatesResponse<TbiomesCells = unknown, TculturesCells = unknown, TreligionsCells = unknown, Texpand = unknown> = Required<StatesRecord<TbiomesCells, TculturesCells, TreligionsCells>> & BaseSystemFields<Texpand>
|
||||
export type TurnsResponse<Texpand = unknown> = Required<TurnsRecord> & BaseSystemFields<Texpand>
|
||||
export type UsersResponse<Texpand = unknown> = Required<UsersRecord> & AuthSystemFields<Texpand>
|
||||
export type BurgsResponse<Temblem = unknown, Texpand = unknown> = Required<BurgsRecord<Temblem>> &
|
||||
BaseSystemFields<Texpand>;
|
||||
export type CulturesResponse<Texpand = unknown> = Required<CulturesRecord> &
|
||||
BaseSystemFields<Texpand>;
|
||||
export type MapsResponse<Texpand = unknown> = Required<MapsRecord> & BaseSystemFields<Texpand>;
|
||||
export type ProvincesResponse<Texpand = unknown> = Required<ProvincesRecord> &
|
||||
BaseSystemFields<Texpand>;
|
||||
export type ReligionsResponse<Texpand = unknown> = Required<ReligionsRecord> &
|
||||
BaseSystemFields<Texpand>;
|
||||
export type ReportInputsResponse<Texpand = unknown> = Required<ReportInputsRecord> &
|
||||
BaseSystemFields<Texpand>;
|
||||
export type ReportOutputsResponse<Texpand = unknown> = Required<ReportOutputsRecord> &
|
||||
BaseSystemFields<Texpand>;
|
||||
export type ReportsResponse<Texpand = unknown> = Required<ReportsRecord> &
|
||||
BaseSystemFields<Texpand>;
|
||||
export type StatesResponse<
|
||||
TbiomesCells = unknown,
|
||||
TculturesCells = unknown,
|
||||
TreligionsCells = unknown,
|
||||
Texpand = unknown
|
||||
> = Required<StatesRecord<TbiomesCells, TculturesCells, TreligionsCells>> &
|
||||
BaseSystemFields<Texpand>;
|
||||
export type TurnsResponse<Texpand = unknown> = Required<TurnsRecord> & BaseSystemFields<Texpand>;
|
||||
export type UsersResponse<Texpand = unknown> = Required<UsersRecord> & AuthSystemFields<Texpand>;
|
||||
|
||||
// Types containing all Records and Responses, useful for creating typing helper functions
|
||||
|
||||
export type CollectionRecords = {
|
||||
burgs: BurgsRecord
|
||||
cultures: CulturesRecord
|
||||
maps: MapsRecord
|
||||
provinces: ProvincesRecord
|
||||
religions: ReligionsRecord
|
||||
reportInputs: ReportInputsRecord
|
||||
reportOutputs: ReportOutputsRecord
|
||||
reports: ReportsRecord
|
||||
states: StatesRecord
|
||||
turns: TurnsRecord
|
||||
users: UsersRecord
|
||||
}
|
||||
burgs: BurgsRecord;
|
||||
cultures: CulturesRecord;
|
||||
maps: MapsRecord;
|
||||
provinces: ProvincesRecord;
|
||||
religions: ReligionsRecord;
|
||||
reportInputs: ReportInputsRecord;
|
||||
reportOutputs: ReportOutputsRecord;
|
||||
reports: ReportsRecord;
|
||||
states: StatesRecord;
|
||||
turns: TurnsRecord;
|
||||
users: UsersRecord;
|
||||
};
|
||||
|
||||
export type CollectionResponses = {
|
||||
burgs: BurgsResponse
|
||||
cultures: CulturesResponse
|
||||
maps: MapsResponse
|
||||
provinces: ProvincesResponse
|
||||
religions: ReligionsResponse
|
||||
reportInputs: ReportInputsResponse
|
||||
reportOutputs: ReportOutputsResponse
|
||||
reports: ReportsResponse
|
||||
states: StatesResponse
|
||||
turns: TurnsResponse
|
||||
users: UsersResponse
|
||||
}
|
||||
burgs: BurgsResponse;
|
||||
cultures: CulturesResponse;
|
||||
maps: MapsResponse;
|
||||
provinces: ProvincesResponse;
|
||||
religions: ReligionsResponse;
|
||||
reportInputs: ReportInputsResponse;
|
||||
reportOutputs: ReportOutputsResponse;
|
||||
reports: ReportsResponse;
|
||||
states: StatesResponse;
|
||||
turns: TurnsResponse;
|
||||
users: UsersResponse;
|
||||
};
|
||||
|
||||
// Type for usage with type asserted PocketBase instance
|
||||
// https://github.com/pocketbase/js-sdk#specify-typescript-definitions
|
||||
|
||||
export type TypedPocketBase = PocketBase & {
|
||||
collection(idOrName: 'burgs'): RecordService<BurgsResponse>
|
||||
collection(idOrName: 'cultures'): RecordService<CulturesResponse>
|
||||
collection(idOrName: 'maps'): RecordService<MapsResponse>
|
||||
collection(idOrName: 'provinces'): RecordService<ProvincesResponse>
|
||||
collection(idOrName: 'religions'): RecordService<ReligionsResponse>
|
||||
collection(idOrName: 'reportInputs'): RecordService<ReportInputsResponse>
|
||||
collection(idOrName: 'reportOutputs'): RecordService<ReportOutputsResponse>
|
||||
collection(idOrName: 'reports'): RecordService<ReportsResponse>
|
||||
collection(idOrName: 'states'): RecordService<StatesResponse>
|
||||
collection(idOrName: 'turns'): RecordService<TurnsResponse>
|
||||
collection(idOrName: 'users'): RecordService<UsersResponse>
|
||||
}
|
||||
collection(idOrName: 'burgs'): RecordService<BurgsResponse>;
|
||||
collection(idOrName: 'cultures'): RecordService<CulturesResponse>;
|
||||
collection(idOrName: 'maps'): RecordService<MapsResponse>;
|
||||
collection(idOrName: 'provinces'): RecordService<ProvincesResponse>;
|
||||
collection(idOrName: 'religions'): RecordService<ReligionsResponse>;
|
||||
collection(idOrName: 'reportInputs'): RecordService<ReportInputsResponse>;
|
||||
collection(idOrName: 'reportOutputs'): RecordService<ReportOutputsResponse>;
|
||||
collection(idOrName: 'reports'): RecordService<ReportsResponse>;
|
||||
collection(idOrName: 'states'): RecordService<StatesResponse>;
|
||||
collection(idOrName: 'turns'): RecordService<TurnsResponse>;
|
||||
collection(idOrName: 'users'): RecordService<UsersResponse>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user