@aerogel/core 0.0.0-next.aa6e27a9c197d1ee10c9fe018ee8c0fc6ff77767 → 0.0.0-next.abea39863ad0f7c484b8b1f365870e43e9bdd0ba
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aerogel-core.css +1 -0
- package/dist/aerogel-core.d.ts +683 -579
- package/dist/aerogel-core.js +2180 -1828
- package/dist/aerogel-core.js.map +1 -1
- package/package.json +7 -2
- package/src/components/AppLayout.vue +1 -3
- package/src/components/AppOverlays.vue +0 -27
- package/src/components/contracts/AlertModal.ts +15 -0
- package/src/components/contracts/ConfirmModal.ts +12 -5
- package/src/components/contracts/DropdownMenu.ts +17 -3
- package/src/components/contracts/ErrorReportModal.ts +8 -4
- package/src/components/contracts/Input.ts +7 -7
- package/src/components/contracts/LoadingModal.ts +12 -4
- package/src/components/contracts/Modal.ts +12 -4
- package/src/components/contracts/PromptModal.ts +8 -2
- package/src/components/contracts/Select.ts +21 -12
- package/src/components/contracts/Toast.ts +4 -2
- package/src/components/contracts/index.ts +3 -1
- package/src/components/headless/HeadlessButton.vue +2 -1
- package/src/components/headless/HeadlessInput.vue +3 -3
- package/src/components/headless/HeadlessInputInput.vue +6 -6
- package/src/components/headless/HeadlessInputTextArea.vue +4 -4
- package/src/components/headless/HeadlessModal.vue +22 -51
- package/src/components/headless/HeadlessModalContent.vue +11 -5
- package/src/components/headless/HeadlessModalDescription.vue +12 -0
- package/src/components/headless/HeadlessSelect.vue +34 -19
- package/src/components/headless/HeadlessSelectOption.vue +1 -1
- package/src/components/headless/HeadlessSelectOptions.vue +16 -4
- package/src/components/headless/HeadlessSelectValue.vue +4 -1
- package/src/components/headless/HeadlessSwitch.vue +96 -0
- package/src/components/headless/index.ts +2 -0
- package/src/components/index.ts +2 -1
- package/src/components/ui/AdvancedOptions.vue +1 -1
- package/src/components/ui/AlertModal.vue +7 -3
- package/src/components/ui/Button.vue +33 -16
- package/src/components/ui/Checkbox.vue +5 -5
- package/src/components/ui/ConfirmModal.vue +12 -4
- package/src/components/ui/DropdownMenu.vue +18 -19
- package/src/components/ui/DropdownMenuOption.vue +22 -0
- package/src/components/ui/DropdownMenuOptions.vue +44 -0
- package/src/components/ui/EditableContent.vue +4 -4
- package/src/components/ui/ErrorLogs.vue +19 -0
- package/src/components/ui/ErrorLogsModal.vue +48 -0
- package/src/components/ui/ErrorReportModal.vue +18 -7
- package/src/components/ui/Input.vue +4 -4
- package/src/components/ui/LoadingModal.vue +6 -4
- package/src/components/ui/Markdown.vue +31 -3
- package/src/components/ui/Modal.vue +83 -22
- package/src/components/ui/ModalContext.vue +2 -1
- package/src/components/ui/ProgressBar.vue +9 -8
- package/src/components/ui/PromptModal.vue +8 -5
- package/src/components/ui/Select.vue +10 -4
- package/src/components/ui/SelectLabel.vue +13 -2
- package/src/components/ui/SelectOption.vue +29 -0
- package/src/components/ui/SelectOptions.vue +24 -20
- package/src/components/ui/SelectTrigger.vue +3 -3
- package/src/components/ui/SettingsModal.vue +4 -40
- package/src/components/ui/Switch.vue +11 -0
- package/src/components/ui/Toast.vue +20 -16
- package/src/components/ui/index.ts +6 -0
- package/src/directives/measure.ts +11 -5
- package/src/errors/Errors.ts +18 -15
- package/src/errors/index.ts +6 -2
- package/src/errors/settings/Debug.vue +39 -0
- package/src/errors/settings/index.ts +10 -0
- package/src/forms/FormController.test.ts +32 -9
- package/src/forms/FormController.ts +23 -22
- package/src/forms/index.ts +0 -1
- package/src/forms/utils.ts +34 -34
- package/src/index.css +37 -5
- package/src/lang/index.ts +5 -1
- package/src/lang/settings/Language.vue +48 -0
- package/src/lang/settings/index.ts +10 -0
- package/src/services/App.state.ts +11 -1
- package/src/services/App.ts +9 -1
- package/src/services/Events.test.ts +8 -8
- package/src/services/Events.ts +2 -8
- package/src/services/index.ts +5 -2
- package/src/testing/index.ts +4 -0
- package/src/ui/UI.state.ts +3 -13
- package/src/ui/UI.ts +107 -83
- package/src/ui/index.ts +16 -17
- package/src/utils/classes.ts +41 -0
- package/src/utils/composition/events.ts +2 -4
- package/src/utils/composition/forms.ts +16 -1
- package/src/utils/composition/state.ts +11 -2
- package/src/utils/index.ts +3 -1
- package/src/utils/markdown.ts +35 -1
- package/src/utils/types.ts +3 -0
- package/src/utils/vue.ts +28 -125
- package/src/components/composition.ts +0 -23
- package/src/components/contracts/shared.ts +0 -9
- package/src/components/utils.ts +0 -107
- package/src/forms/composition.ts +0 -6
- package/src/utils/tailwindcss.test.ts +0 -26
- package/src/utils/tailwindcss.ts +0 -7
- package/src/utils/vdom.ts +0 -31
package/src/forms/utils.ts
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
import { FormFieldTypes } from './FormController';
|
|
2
1
|
import type { FormFieldDefinition } from './FormController';
|
|
3
2
|
|
|
4
|
-
export function booleanInput(
|
|
5
|
-
defaultValue?: boolean,
|
|
6
|
-
options: { rules?: string } = {},
|
|
7
|
-
): FormFieldDefinition<typeof FormFieldTypes.Boolean> {
|
|
3
|
+
export function booleanInput(defaultValue?: boolean, options: { rules?: string } = {}): FormFieldDefinition<'boolean'> {
|
|
8
4
|
return {
|
|
9
5
|
default: defaultValue,
|
|
10
|
-
type:
|
|
6
|
+
type: 'boolean',
|
|
11
7
|
rules: options.rules,
|
|
12
8
|
};
|
|
13
9
|
}
|
|
14
10
|
|
|
15
|
-
export function dateInput(
|
|
16
|
-
defaultValue?: Date,
|
|
17
|
-
options: { rules?: string } = {},
|
|
18
|
-
): FormFieldDefinition<typeof FormFieldTypes.Date> {
|
|
11
|
+
export function dateInput(defaultValue?: Date, options: { rules?: string } = {}): FormFieldDefinition<'date'> {
|
|
19
12
|
return {
|
|
20
13
|
default: defaultValue,
|
|
21
|
-
type:
|
|
14
|
+
type: 'date',
|
|
22
15
|
rules: options.rules,
|
|
23
16
|
};
|
|
24
17
|
}
|
|
25
18
|
|
|
26
|
-
export function requiredBooleanInput(
|
|
27
|
-
defaultValue?: boolean,
|
|
28
|
-
): FormFieldDefinition<typeof FormFieldTypes.Boolean, 'required'> {
|
|
19
|
+
export function requiredBooleanInput(defaultValue?: boolean): FormFieldDefinition<'boolean', 'required'> {
|
|
29
20
|
return {
|
|
30
21
|
default: defaultValue,
|
|
31
|
-
type:
|
|
22
|
+
type: 'boolean',
|
|
32
23
|
rules: 'required',
|
|
33
24
|
};
|
|
34
25
|
}
|
|
35
26
|
|
|
36
|
-
export function requiredDateInput(defaultValue?: Date): FormFieldDefinition<
|
|
27
|
+
export function requiredDateInput(defaultValue?: Date): FormFieldDefinition<'date', 'required'> {
|
|
37
28
|
return {
|
|
38
29
|
default: defaultValue,
|
|
39
|
-
type:
|
|
30
|
+
type: 'date',
|
|
40
31
|
rules: 'required',
|
|
41
32
|
};
|
|
42
33
|
}
|
|
43
34
|
|
|
44
|
-
export function requiredNumberInput(
|
|
45
|
-
defaultValue?: number,
|
|
46
|
-
): FormFieldDefinition<typeof FormFieldTypes.Number, 'required'> {
|
|
35
|
+
export function requiredNumberInput(defaultValue?: number): FormFieldDefinition<'number', 'required'> {
|
|
47
36
|
return {
|
|
48
37
|
default: defaultValue,
|
|
49
|
-
type:
|
|
38
|
+
type: 'number',
|
|
50
39
|
rules: 'required',
|
|
51
40
|
};
|
|
52
41
|
}
|
|
53
42
|
|
|
54
|
-
export function
|
|
55
|
-
defaultValue?: string,
|
|
56
|
-
): FormFieldDefinition<typeof FormFieldTypes.String, 'required'> {
|
|
43
|
+
export function requiredObjectInput<T extends object>(defaultValue?: T): FormFieldDefinition<'object', 'required', T> {
|
|
57
44
|
return {
|
|
58
45
|
default: defaultValue,
|
|
59
|
-
type:
|
|
46
|
+
type: 'object',
|
|
60
47
|
rules: 'required',
|
|
61
48
|
};
|
|
62
49
|
}
|
|
63
50
|
|
|
64
|
-
export function
|
|
65
|
-
defaultValue?: number,
|
|
66
|
-
options: { rules?: string } = {},
|
|
67
|
-
): FormFieldDefinition<typeof FormFieldTypes.Number> {
|
|
51
|
+
export function requiredStringInput(defaultValue?: string): FormFieldDefinition<'string', 'required'> {
|
|
68
52
|
return {
|
|
69
53
|
default: defaultValue,
|
|
70
|
-
type:
|
|
54
|
+
type: 'string',
|
|
55
|
+
rules: 'required',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function numberInput(defaultValue?: number, options: { rules?: string } = {}): FormFieldDefinition<'number'> {
|
|
60
|
+
return {
|
|
61
|
+
default: defaultValue,
|
|
62
|
+
type: 'number',
|
|
71
63
|
rules: options.rules,
|
|
72
64
|
};
|
|
73
65
|
}
|
|
74
66
|
|
|
75
|
-
export function
|
|
76
|
-
defaultValue?:
|
|
67
|
+
export function objectInput<T extends object>(
|
|
68
|
+
defaultValue?: T,
|
|
77
69
|
options: { rules?: string } = {},
|
|
78
|
-
): FormFieldDefinition<
|
|
70
|
+
): FormFieldDefinition<'object', string, T> {
|
|
71
|
+
return {
|
|
72
|
+
default: defaultValue,
|
|
73
|
+
type: 'object',
|
|
74
|
+
rules: options.rules,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function stringInput(defaultValue?: string, options: { rules?: string } = {}): FormFieldDefinition<'string'> {
|
|
79
79
|
return {
|
|
80
80
|
default: defaultValue,
|
|
81
|
-
type:
|
|
81
|
+
type: 'string',
|
|
82
82
|
rules: options.rules,
|
|
83
83
|
};
|
|
84
84
|
}
|
package/src/index.css
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
2
|
+
|
|
3
|
+
@plugin '@tailwindcss/forms';
|
|
4
|
+
@plugin '@tailwindcss/typography';
|
|
5
|
+
|
|
1
6
|
@source './';
|
|
2
|
-
@source '../../plugin-local-first/src';
|
|
3
|
-
@source '../../plugin-solid/src';
|
|
4
7
|
|
|
5
8
|
@theme {
|
|
6
|
-
--color-background: oklch(1 0 0);
|
|
7
9
|
--color-primary: oklch(0.205 0 0);
|
|
8
|
-
--color-
|
|
9
|
-
--color-
|
|
10
|
+
--color-primary-50: color-mix(in oklab, var(--color-primary-600) 5%, transparent);
|
|
11
|
+
--color-primary-100: color-mix(in oklab, var(--color-primary-600) 15%, transparent);
|
|
12
|
+
--color-primary-200: color-mix(in oklab, var(--color-primary-600) 30%, transparent);
|
|
13
|
+
--color-primary-300: color-mix(in oklab, var(--color-primary-600) 50%, transparent);
|
|
14
|
+
--color-primary-400: color-mix(in oklab, var(--color-primary-600) 65%, transparent);
|
|
15
|
+
--color-primary-500: color-mix(in oklab, var(--color-primary-600) 80%, transparent);
|
|
16
|
+
--color-primary-600: var(--color-primary);
|
|
17
|
+
--color-primary-700: color-mix(in oklab, var(--color-primary-600) 90%, black);
|
|
18
|
+
--color-primary-800: color-mix(in oklab, var(--color-primary-600) 80%, black);
|
|
19
|
+
--color-primary-900: color-mix(in oklab, var(--color-primary-600) 70%, black);
|
|
20
|
+
--color-primary-950: color-mix(in oklab, var(--color-primary-600) 50%, black);
|
|
21
|
+
|
|
22
|
+
--color-background: oklch(1 0 0);
|
|
23
|
+
--color-links: var(--color-primary);
|
|
10
24
|
}
|
|
11
25
|
|
|
12
26
|
.clickable {
|
|
@@ -39,3 +53,21 @@ button[data-markdown-action] {
|
|
|
39
53
|
text-decoration: underline;
|
|
40
54
|
font-weight: 500;
|
|
41
55
|
}
|
|
56
|
+
|
|
57
|
+
@keyframes fade-in {
|
|
58
|
+
0% {
|
|
59
|
+
opacity: 0;
|
|
60
|
+
}
|
|
61
|
+
100% {
|
|
62
|
+
opacity: 1;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@keyframes grow {
|
|
67
|
+
0% {
|
|
68
|
+
scale: 0;
|
|
69
|
+
}
|
|
70
|
+
100% {
|
|
71
|
+
opacity: 1;
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/lang/index.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import App from '@aerogel/core/services/App';
|
|
1
2
|
import { bootServices } from '@aerogel/core/services';
|
|
2
3
|
import { definePlugin } from '@aerogel/core/plugins';
|
|
3
4
|
|
|
4
5
|
import Lang from './Lang';
|
|
5
|
-
import
|
|
6
|
+
import settings from './settings';
|
|
6
7
|
import { translate, translateWithDefault } from './utils';
|
|
8
|
+
import type { LangProvider } from './Lang';
|
|
7
9
|
|
|
8
10
|
export { Lang, translate, translateWithDefault };
|
|
9
11
|
export type { LangProvider };
|
|
@@ -17,6 +19,8 @@ export default definePlugin({
|
|
|
17
19
|
app.config.globalProperties.$t ??= translate;
|
|
18
20
|
app.config.globalProperties.$td = translateWithDefault;
|
|
19
21
|
|
|
22
|
+
settings.forEach((setting) => App.addSetting(setting));
|
|
23
|
+
|
|
20
24
|
await bootServices(app, services);
|
|
21
25
|
},
|
|
22
26
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Select
|
|
3
|
+
v-model="$lang.locale"
|
|
4
|
+
class="flex flex-col items-start md:flex-row"
|
|
5
|
+
as="div"
|
|
6
|
+
:options
|
|
7
|
+
:render-option="renderLocale"
|
|
8
|
+
>
|
|
9
|
+
<div class="grow">
|
|
10
|
+
<SelectLabel class="text-base font-semibold">
|
|
11
|
+
{{ $td('settings.locale', 'Language') }}
|
|
12
|
+
</SelectLabel>
|
|
13
|
+
<Markdown
|
|
14
|
+
lang-key="settings.localeDescription"
|
|
15
|
+
lang-default="Choose the application's language."
|
|
16
|
+
class="mt-1 text-sm text-gray-500"
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
<Button variant="ghost" :as="SelectTrigger" class="grid w-auto outline-none" />
|
|
20
|
+
<SelectOptions />
|
|
21
|
+
</Select>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
import Aerogel from 'virtual:aerogel';
|
|
26
|
+
|
|
27
|
+
import { computed } from 'vue';
|
|
28
|
+
|
|
29
|
+
import Markdown from '@aerogel/core/components/ui/Markdown.vue';
|
|
30
|
+
import Button from '@aerogel/core/components/ui/Button.vue';
|
|
31
|
+
import Select from '@aerogel/core/components/ui/Select.vue';
|
|
32
|
+
import SelectLabel from '@aerogel/core/components/ui/SelectLabel.vue';
|
|
33
|
+
import SelectTrigger from '@aerogel/core/components/ui/SelectTrigger.vue';
|
|
34
|
+
import SelectOptions from '@aerogel/core/components/ui/SelectOptions.vue';
|
|
35
|
+
import { Lang, translateWithDefault } from '@aerogel/core/lang';
|
|
36
|
+
|
|
37
|
+
const browserLocale = Lang.getBrowserLocale();
|
|
38
|
+
const options = computed(() => [null, ...Lang.locales]);
|
|
39
|
+
|
|
40
|
+
function renderLocale(locale: string | null): string {
|
|
41
|
+
return (
|
|
42
|
+
(locale && Aerogel.locales[locale]) ??
|
|
43
|
+
translateWithDefault('settings.localeDefault', '{locale} (default)', {
|
|
44
|
+
locale: Aerogel.locales[browserLocale] ?? browserLocale,
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import Aerogel from 'virtual:aerogel';
|
|
2
2
|
|
|
3
3
|
import { getEnv } from '@noeldemartin/utils';
|
|
4
|
-
import type { App } from 'vue';
|
|
4
|
+
import type { App, Component } from 'vue';
|
|
5
5
|
|
|
6
6
|
import { defineServiceState } from '@aerogel/core/services/Service';
|
|
7
7
|
import type { Plugin } from '@aerogel/core/plugins/Plugin';
|
|
8
8
|
|
|
9
|
+
export interface AppSetting {
|
|
10
|
+
component: Component;
|
|
11
|
+
priority: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function defineSettings<T extends AppSetting[]>(settings: T): T {
|
|
15
|
+
return settings;
|
|
16
|
+
}
|
|
17
|
+
|
|
9
18
|
export default defineServiceState({
|
|
10
19
|
name: 'app',
|
|
11
20
|
initialState: {
|
|
@@ -14,6 +23,7 @@ export default defineServiceState({
|
|
|
14
23
|
environment: getEnv() ?? 'development',
|
|
15
24
|
version: Aerogel.version,
|
|
16
25
|
sourceUrl: Aerogel.sourceUrl,
|
|
26
|
+
settings: [] as AppSetting[],
|
|
17
27
|
},
|
|
18
28
|
computed: {
|
|
19
29
|
development: (state) => state.environment === 'development',
|
package/src/services/App.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import Aerogel from 'virtual:aerogel';
|
|
2
2
|
|
|
3
3
|
import { PromisedValue, facade, forever, updateLocationQueryParameters } from '@noeldemartin/utils';
|
|
4
|
+
import { markRaw } from 'vue';
|
|
4
5
|
|
|
5
6
|
import Events from '@aerogel/core/services/Events';
|
|
6
7
|
import type { Plugin } from '@aerogel/core/plugins';
|
|
7
|
-
import type { Services } from '@aerogel/core/services';
|
|
8
|
+
import type { AppSetting, Services } from '@aerogel/core/services';
|
|
8
9
|
|
|
9
10
|
import Service from './App.state';
|
|
10
11
|
|
|
12
|
+
export { defineSettings } from './App.state';
|
|
13
|
+
export type { AppSetting } from './App.state';
|
|
14
|
+
|
|
11
15
|
export class AppService extends Service {
|
|
12
16
|
|
|
13
17
|
public readonly name = Aerogel.name;
|
|
@@ -22,6 +26,10 @@ export class AppService extends Service {
|
|
|
22
26
|
return this.mounted.isResolved();
|
|
23
27
|
}
|
|
24
28
|
|
|
29
|
+
public addSetting(setting: AppSetting): void {
|
|
30
|
+
this.settings.push(markRaw(setting));
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
public async whenReady<T>(callback: () => T): Promise<T> {
|
|
26
34
|
const result = await this.ready.then(callback);
|
|
27
35
|
|
|
@@ -10,12 +10,12 @@ describe('Events', () => {
|
|
|
10
10
|
// Arrange
|
|
11
11
|
let counter = 0;
|
|
12
12
|
|
|
13
|
-
Events.on('
|
|
13
|
+
Events.on('application-mounted', () => counter++);
|
|
14
14
|
|
|
15
15
|
// Act
|
|
16
|
-
await Events.emit('
|
|
17
|
-
await Events.emit('
|
|
18
|
-
await Events.emit('
|
|
16
|
+
await Events.emit('application-mounted');
|
|
17
|
+
await Events.emit('application-mounted');
|
|
18
|
+
await Events.emit('application-mounted');
|
|
19
19
|
|
|
20
20
|
// Assert
|
|
21
21
|
expect(counter).toEqual(3);
|
|
@@ -25,12 +25,12 @@ describe('Events', () => {
|
|
|
25
25
|
// Arrange
|
|
26
26
|
const storage: string[] = [];
|
|
27
27
|
|
|
28
|
-
Events.on('
|
|
29
|
-
Events.on('
|
|
30
|
-
Events.on('
|
|
28
|
+
Events.on('application-mounted', () => storage.push('second'));
|
|
29
|
+
Events.on('application-mounted', { priority: EventListenerPriorities.Low }, () => storage.push('third'));
|
|
30
|
+
Events.on('application-mounted', { priority: EventListenerPriorities.High }, () => storage.push('first'));
|
|
31
31
|
|
|
32
32
|
// Act
|
|
33
|
-
await Events.emit('
|
|
33
|
+
await Events.emit('application-mounted');
|
|
34
34
|
|
|
35
35
|
// Assert
|
|
36
36
|
expect(storage).toEqual(['first', 'second', 'third']);
|
package/src/services/Events.ts
CHANGED
|
@@ -10,7 +10,6 @@ export type AerogelGlobalEvents = Partial<{ [Event in EventWithoutPayload]: () =
|
|
|
10
10
|
Partial<{ [Event in EventWithPayload]: EventListener<EventsPayload[Event]> }>;
|
|
11
11
|
|
|
12
12
|
export type EventListener<T = unknown> = (payload: T) => unknown;
|
|
13
|
-
export type UnknownEvent<T> = T extends keyof EventsPayload ? never : T;
|
|
14
13
|
|
|
15
14
|
export type EventWithoutPayload = {
|
|
16
15
|
[K in keyof EventsPayload]: EventsPayload[K] extends void ? K : never;
|
|
@@ -34,12 +33,12 @@ export class EventsService extends Service {
|
|
|
34
33
|
|
|
35
34
|
protected override async boot(): Promise<void> {
|
|
36
35
|
Object.entries(globalThis.__aerogelEvents__ ?? {}).forEach(([event, listener]) =>
|
|
37
|
-
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
this.on(event as any, listener as EventListener));
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
public emit<Event extends EventWithoutPayload>(event: Event): Promise<void>;
|
|
41
41
|
public emit<Event extends EventWithPayload>(event: Event, payload: EventsPayload[Event]): Promise<void>;
|
|
42
|
-
public emit<Event extends string>(event: UnknownEvent<Event>, payload?: unknown): Promise<void>;
|
|
43
42
|
public async emit(event: string, payload?: unknown): Promise<void> {
|
|
44
43
|
const listeners = this.listeners[event] ?? { priorities: [], handlers: {} };
|
|
45
44
|
|
|
@@ -55,9 +54,6 @@ export class EventsService extends Service {
|
|
|
55
54
|
public on<Event extends EventWithPayload>(event: Event, listener: EventListener<EventsPayload[Event]>): () => void | void; // prettier-ignore
|
|
56
55
|
public on<Event extends EventWithPayload>(event: Event, priority: EventListenerPriority, listener: EventListener<EventsPayload[Event]>): () => void | void; // prettier-ignore
|
|
57
56
|
public on<Event extends EventWithPayload>(event: Event, options: Partial<EventListenerOptions>, listener: EventListener<EventsPayload[Event]>): () => void | void; // prettier-ignore
|
|
58
|
-
public on<Event extends string>(event: UnknownEvent<Event>, listener: EventListener): () => void;
|
|
59
|
-
public on<Event extends string>(event: UnknownEvent<Event>, priority: EventListenerPriority, listener: EventListener): () => void; // prettier-ignore
|
|
60
|
-
public on<Event extends string>(event: UnknownEvent<Event>, options: Partial<EventListenerOptions>, listener: EventListener): () => void; // prettier-ignore
|
|
61
57
|
/* eslint-enable max-len */
|
|
62
58
|
|
|
63
59
|
public on(
|
|
@@ -83,8 +79,6 @@ export class EventsService extends Service {
|
|
|
83
79
|
public once<Event extends EventWithoutPayload>(event: Event, options: Partial<EventListenerOptions>, listener: () => unknown): () => void; // prettier-ignore
|
|
84
80
|
public once<Event extends EventWithPayload>(event: Event, listener: EventListener<EventsPayload[Event]>): () => void | void; // prettier-ignore
|
|
85
81
|
public once<Event extends EventWithPayload>(event: Event, options: Partial<EventListenerOptions>, listener: EventListener<EventsPayload[Event]>): () => void | void; // prettier-ignore
|
|
86
|
-
public once<Event extends string>(event: UnknownEvent<Event>, listener: EventListener): () => void;
|
|
87
|
-
public once<Event extends string>(event: UnknownEvent<Event>, options: Partial<EventListenerOptions>, listener: EventListener): () => void; // prettier-ignore
|
|
88
82
|
/* eslint-enable max-len */
|
|
89
83
|
|
|
90
84
|
public once(
|
package/src/services/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { App as
|
|
1
|
+
import type { App as AppInstance } from 'vue';
|
|
2
2
|
|
|
3
3
|
import { definePlugin } from '@aerogel/core/plugins';
|
|
4
4
|
import { isDevelopment, isTesting } from '@noeldemartin/utils';
|
|
@@ -9,6 +9,7 @@ import Events from './Events';
|
|
|
9
9
|
import Service from './Service';
|
|
10
10
|
import Storage from './Storage';
|
|
11
11
|
import { getPiniaStore } from './store';
|
|
12
|
+
import type { AppSetting } from './App.state';
|
|
12
13
|
|
|
13
14
|
export * from './App';
|
|
14
15
|
export * from './Cache';
|
|
@@ -29,7 +30,7 @@ export type DefaultServices = typeof defaultServices;
|
|
|
29
30
|
|
|
30
31
|
export interface Services extends DefaultServices {}
|
|
31
32
|
|
|
32
|
-
export async function bootServices(app:
|
|
33
|
+
export async function bootServices(app: AppInstance, services: Record<string, Service>): Promise<void> {
|
|
33
34
|
await Promise.all(
|
|
34
35
|
Object.entries(services).map(async ([name, service]) => {
|
|
35
36
|
await service
|
|
@@ -53,6 +54,7 @@ export default definePlugin({
|
|
|
53
54
|
};
|
|
54
55
|
|
|
55
56
|
app.use(getPiniaStore());
|
|
57
|
+
options.settings?.forEach((setting) => App.addSetting(setting));
|
|
56
58
|
|
|
57
59
|
await bootServices(app, services);
|
|
58
60
|
},
|
|
@@ -61,6 +63,7 @@ export default definePlugin({
|
|
|
61
63
|
declare module '@aerogel/core/bootstrap/options' {
|
|
62
64
|
export interface AerogelOptions {
|
|
63
65
|
services?: Record<string, Service>;
|
|
66
|
+
settings?: AppSetting[];
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
69
|
|
package/src/testing/index.ts
CHANGED
|
@@ -2,10 +2,13 @@ import { isTesting } from '@noeldemartin/utils';
|
|
|
2
2
|
import type { GetClosureArgs } from '@noeldemartin/utils';
|
|
3
3
|
|
|
4
4
|
import Events from '@aerogel/core/services/Events';
|
|
5
|
+
import { App } from '@aerogel/core/services';
|
|
5
6
|
import { definePlugin } from '@aerogel/core/plugins';
|
|
7
|
+
import type { Services } from '@aerogel/core/services';
|
|
6
8
|
|
|
7
9
|
export interface AerogelTestingRuntime {
|
|
8
10
|
on: (typeof Events)['on'];
|
|
11
|
+
service<T extends keyof Services>(name: T): Services[T] | null;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
export default definePlugin({
|
|
@@ -16,6 +19,7 @@ export default definePlugin({
|
|
|
16
19
|
|
|
17
20
|
globalThis.testingRuntime = {
|
|
18
21
|
on: ((...args: GetClosureArgs<(typeof Events)['on']>) => Events.on(...args)) as (typeof Events)['on'],
|
|
22
|
+
service: (name) => App.service(name),
|
|
19
23
|
};
|
|
20
24
|
},
|
|
21
25
|
});
|
package/src/ui/UI.state.ts
CHANGED
|
@@ -8,22 +8,11 @@ export interface UIModal<T = unknown> {
|
|
|
8
8
|
id: string;
|
|
9
9
|
properties: Record<string, unknown>;
|
|
10
10
|
component: Component;
|
|
11
|
+
closing: boolean;
|
|
11
12
|
beforeClose: Promise<T | undefined>;
|
|
12
13
|
afterClose: Promise<T | undefined>;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
export interface UIModalContext {
|
|
16
|
-
modal: UIModal;
|
|
17
|
-
childIndex?: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface ModalComponent<
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
22
|
-
Properties extends object = object,
|
|
23
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
24
|
-
Result = unknown,
|
|
25
|
-
> {}
|
|
26
|
-
|
|
27
16
|
export interface UIToast {
|
|
28
17
|
id: string;
|
|
29
18
|
component: Component;
|
|
@@ -38,7 +27,8 @@ export default defineServiceState({
|
|
|
38
27
|
layout: getCurrentLayout(),
|
|
39
28
|
},
|
|
40
29
|
computed: {
|
|
41
|
-
mobile: ({ layout }) => layout === Layouts.Mobile,
|
|
42
30
|
desktop: ({ layout }) => layout === Layouts.Desktop,
|
|
31
|
+
mobile: ({ layout }) => layout === Layouts.Mobile,
|
|
32
|
+
openModals: ({ modals }) => modals.filter(({ closing }) => !closing),
|
|
43
33
|
},
|
|
44
34
|
});
|