Merge pull request 'refactor: improvemets' (#41) from refactor/improvements into main
All checks were successful
Renovate / renovate (push) Successful in 1m57s

Reviewed-on: #41
This commit was merged in pull request #41.
This commit is contained in:
2026-03-24 23:15:11 +00:00
6 changed files with 130 additions and 10 deletions

View File

@@ -1,11 +1,13 @@
<template> <template>
<RouterView></RouterView> <RouterView></RouterView>
<SharedSnackbar />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { RouterView } from 'vue-router'; import { RouterView } from 'vue-router';
import { onMounted, watch } from 'vue'; import { onMounted, watch } from 'vue';
import { useTheme } from 'vuetify'; import { useTheme } from 'vuetify';
import SharedSnackbar from '@KTXC/components/shared/SharedSnackbar.vue';
import { useLayoutStore } from '@KTXC/stores/layoutStore'; import { useLayoutStore } from '@KTXC/stores/layoutStore';
import { useUserStore } from '@KTXC/stores/userStore'; import { useUserStore } from '@KTXC/stores/userStore';
import { useTenantStore } from '@KTXC/stores/tenantStore'; import { useTenantStore } from '@KTXC/stores/tenantStore';

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
import { useSnackbar } from '@KTXC/composables/useSnackbar'
const {
snackbarVisible,
snackbarMessage,
snackbarColor,
snackbarTimeout,
hideSnackbar,
} = useSnackbar()
</script>
<template>
<v-snackbar
:model-value="snackbarVisible"
:color="snackbarColor"
:timeout="snackbarTimeout"
location="bottom right"
@update:model-value="value => !value && hideSnackbar()"
>
{{ snackbarMessage }}
<template #actions>
<v-btn variant="text" @click="hideSnackbar()">
Close
</v-btn>
</template>
</v-snackbar>
</template>

View File

@@ -2,7 +2,7 @@
* Simple snackbar/toast notification composable * Simple snackbar/toast notification composable
* Uses Vuetify's snackbar component * Uses Vuetify's snackbar component
*/ */
import { ref } from 'vue' import { nextTick, ref } from 'vue'
export interface SnackbarOptions { export interface SnackbarOptions {
message: string message: string
@@ -10,21 +10,60 @@ export interface SnackbarOptions {
timeout?: number timeout?: number
} }
interface SnackbarState {
message: string
color: string
timeout: number
}
const snackbarVisible = ref(false) const snackbarVisible = ref(false)
const snackbarMessage = ref('') const snackbarMessage = ref('')
const snackbarColor = ref<string>('info') const snackbarColor = ref<string>('info')
const snackbarTimeout = ref(3000) const snackbarTimeout = ref(3000)
const snackbarQueue = ref<SnackbarState[]>([])
function showNextSnackbar() {
if (snackbarVisible.value || snackbarQueue.value.length === 0) {
return
}
const nextSnackbar = snackbarQueue.value.shift()
if (!nextSnackbar) {
return
}
snackbarMessage.value = nextSnackbar.message
snackbarColor.value = nextSnackbar.color
snackbarTimeout.value = nextSnackbar.timeout
snackbarVisible.value = true
}
export function useSnackbar() { export function useSnackbar() {
const showSnackbar = (options: SnackbarOptions) => { const showSnackbar = (options: SnackbarOptions) => {
snackbarMessage.value = options.message
snackbarColor.value = options.color || 'info' const notification = {
snackbarTimeout.value = options.timeout || 3000 message: options.message,
color: options.color || 'info',
timeout: options.timeout || 3000,
}
if (!snackbarVisible.value && snackbarQueue.value.length === 0) {
snackbarMessage.value = notification.message
snackbarColor.value = notification.color
snackbarTimeout.value = notification.timeout
snackbarVisible.value = true snackbarVisible.value = true
return
}
snackbarQueue.value = [...snackbarQueue.value, notification]
} }
const hideSnackbar = () => { const hideSnackbar = () => {
snackbarVisible.value = false snackbarVisible.value = false
void nextTick(() => {
showNextSnackbar()
})
} }
return { return {
@@ -32,6 +71,7 @@ export function useSnackbar() {
snackbarMessage, snackbarMessage,
snackbarColor, snackbarColor,
snackbarTimeout, snackbarTimeout,
snackbarQueue,
showSnackbar, showSnackbar,
hideSnackbar, hideSnackbar,
} }

View File

@@ -16,6 +16,7 @@ export { useLayoutStore } from '../stores/layoutStore'
// Composables // Composables
export { useUser } from '../composables/useUser' export { useUser } from '../composables/useUser'
export { useClipboard } from '../composables/useClipboard' export { useClipboard } from '../composables/useClipboard'
export { useSnackbar } from '../composables/useSnackbar'
// Services // Services
export { userService } from '../services/user/userService' export { userService } from '../services/user/userService'

View File

@@ -132,7 +132,7 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
public function entityList(string|int|null $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array; public function entityList(string|int|null $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array;
/** /**
* Creates a filter builder for messages * Creates a filter builder for entities
* *
* @since 2025.05.01 * @since 2025.05.01
* *
@@ -141,7 +141,7 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
public function entityListFilter(): IFilter; public function entityListFilter(): IFilter;
/** /**
* Creates a sort builder for messages * Creates a sort builder for entities
* *
* @since 2025.05.01 * @since 2025.05.01
* *
@@ -150,7 +150,7 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
public function entityListSort(): ISort; public function entityListSort(): ISort;
/** /**
* Creates a range builder for messages * Creates a range builder for entities
* *
* @since 2025.05.01 * @since 2025.05.01
* *
@@ -209,4 +209,50 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
*/ */
public function entityRead(string|int|null $collection, string|int $identifier): ?string; public function entityRead(string|int|null $collection, string|int $identifier): ?string;
/**
* Lists messages in a collection
*
* @since 2025.05.01
*
* @param string|int|null $collection Collection ID
* @param IFilter|null $filter Optional filter criteria
* @param ISort|null $sort Optional sort order
* @param IRange|null $range Optional pagination
* @param array|null $properties Optional message properties to fetch
*
* @return array<string|int,CollectionBaseInterface|EntityBaseInterface> Nodes indexed by ID
*/
public function nodeList(string|int|null $collection, bool $recursive = false, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array;
/**
* Creates a filter builder for nodes
*
* @since 2025.05.01
*
* @return IFilter
*/
public function nodeListFilter(): IFilter;
/**
* Creates a sort builder for nodes
*
* @since 2025.05.01
*
* @return ISort
*/
public function nodeListSort(): ISort;
/**
* Gets incremental changes since last sync
*
* @since 2025.05.01
*
* @param string|int|null $collection Collection ID
* @param string $signature Sync token from previous sync
* @param string $detail Detail level: 'ids', 'minimal', 'full'
*
* @return array ['signature' => string, 'added' => array, 'modified' => array, 'removed' => array]
*/
public function nodeDelta(string|int|null $collection, string $signature, string $detail = 'ids'): Delta;
} }

View File

@@ -9,14 +9,16 @@ declare(strict_types=1);
namespace KTXF\Resource\Documents\Service; namespace KTXF\Resource\Documents\Service;
use KTXF\Resource\Provider\ResourceServiceMutateInterface;
/** /**
* Chrono Service Mutable Interface * Documents Service Mutable Interface
* *
* Extends base service interface with setter methods for mutable properties. * Extends base service interface with setter methods for mutable properties.
* Used for service configuration and updates. * Used for service configuration and updates.
* *
* @since 2025.05.01 * @since 2025.05.01
*/ */
interface ServiceMutableInterface extends ServiceBaseInterface { interface ServiceMutableInterface extends ServiceBaseInterface, ResourceServiceMutateInterface {
} }