@webx-ui/module-events 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 webx-ui
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # @webx-ui/module-events
2
+
3
+ The front end of the events section of the [WebX UI](https://github.com/webx-ui/webx-ui) admin
4
+ panel: workshops, meetings and webinars — a date and a time, a place, a price and a link to book,
5
+ a gallery and «What to expect» — and the categories they are filed under.
6
+
7
+ The other half is the Composer package `webx-ui/module-events`, which owns the events, their pages
8
+ and addresses, the `.ics` files, the `Event` markup, `events()` for templates and the API. A section
9
+ appears in the panel when both halves are installed.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install @webx-ui/module-events
15
+ ```
16
+
17
+ ```ts
18
+ import { createAdmin } from '@webx-ui/module-admin'
19
+ import { events } from '@webx-ui/module-events'
20
+ import '@webx-ui/module-events/style.css'
21
+
22
+ createAdmin({
23
+ basePath: '/cms',
24
+ modules: [...events()],
25
+ }).mount()
26
+ ```
27
+
28
+ `events()` answers with two sections — the events and their categories — because the panel draws
29
+ one entry per module. The server puts both in the `events` group. `events({ path: '/calendar' })`
30
+ puts them somewhere else inside the panel.
31
+
32
+ ## What is here
33
+
34
+ - **The list** — a page at a time, with tabs for when: the events to come (the default), the past
35
+ ones, all — the past ones dimmed — and the bin. The date column is the line the site prints, with
36
+ the exact moments in the tip. «Duplicate» is in the row menu.
37
+ - **The editor** — the described screen `events.form` with the tabs Event · Settings · SEO ·
38
+ History, autosaved into a draft and guarded by a revision. The dates travel with their offset,
39
+ so the same event reads the same hour in every browser; an event of days (All day) shows the
40
+ same calendar days everywhere. «Duplicate» in the bar saves, copies and opens the copy. The
41
+ categories and the services wait in the draft with the text and reach the site on «Publish». A
42
+ project adds its own fields with a patch into the `project-fields` card.
43
+ - **Categories** — the panel's shared category screens (`categoryRoutes`), with
44
+ `eventCategoriesOptions()` exported for a panel that mounts them elsewhere.
45
+
46
+ The words are English by default and come from the server in the panel's language
47
+ (`webx-events::`).
48
+
49
+ Documentation: https://webx-ui.github.io/webx-ui/guide/events.html
50
+
51
+ ## License
52
+
53
+ MIT
@@ -0,0 +1,4 @@
1
+ declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
2
+ field: HTMLDivElement;
3
+ }, any>;
4
+ export default _default;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The editor of one event: a head that stays put, the described screen under it, and the bar
3
+ * along the bottom where it is saved, duplicated and published (§4.9).
4
+ *
5
+ * Everything between the head and the bar is `events.form` — the event, its settings, the SEO
6
+ * card `module-seo` patches on and the history — so a project adds its own field with a patch
7
+ * rather than a fork of this file. Saving is by autosave into the draft, and the draft carries
8
+ * the categories and the services too: the site changes, all of it at once, only on "Publish".
9
+ * Edits are guarded by a revision: a save over somebody else's is refused with a 409 and the
10
+ * question of which version the site gets.
11
+ *
12
+ * The dates are moments with their offset (`valueFormat` on the screen's pickers), so the same
13
+ * event reads the same hour in every browser and the server keeps it in its own zone (decision
14
+ * 15). What the head prints under the name is the server's line (`when`, §4.6), not ours: it is
15
+ * the line the site prints, `date_note` included, and a second formatter here would disagree
16
+ * with it sooner or later.
17
+ */
18
+ type __VLS_Props = {
19
+ base?: string;
20
+ };
21
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
22
+ base: string;
23
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
24
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
2
+ export default _default;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The section: a page of events with the filters of §4.9 over it.
3
+ *
4
+ * A paginator and not a sortable list, which is the whole difference from recipes: events have
5
+ * no order of their own — the date is the order (decision 4) — and they pile up for years, so the
6
+ * screen is twenty rows, the filters and a page number.
7
+ *
8
+ * The tabs are *when*, not the state: the upcoming ones are what an editor comes here for and
9
+ * what the site's lists show, so they are the list with nothing chosen. The past ones are a tab
10
+ * away, and "all" draws the past ones muted, so the line between the two can be seen at a glance.
11
+ * The state, the category and the service live behind the funnel.
12
+ *
13
+ * Below {@link CARDS} the row becomes a card, the way the articles do it: the cover on the left,
14
+ * everything else beside it.
15
+ */
16
+ type __VLS_Props = {
17
+ base?: string;
18
+ };
19
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
20
+ base: string;
21
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
22
+ root: HTMLDivElement;
23
+ }, HTMLDivElement>;
24
+ export default _default;
package/dist/api.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ import { AdminContext } from '@webx-ui/module-admin';
2
+ import { EventDetail, EventInput, EventQuery, EventRow, EventSave, EventsPage, EventVersion } from './types';
3
+ export interface EventsApi {
4
+ /** A page of events, with what the list can be narrowed by. */
5
+ list(query?: EventQuery): Promise<EventsPage>;
6
+ /** One event as its editor opens it: the record, the screen's values and the revision. */
7
+ get(id: number): Promise<EventDetail>;
8
+ /** A new event, made in one transaction: a refused address leaves no bare row behind. */
9
+ create(input: EventInput): Promise<EventDetail>;
10
+ /**
11
+ * Save the draft. Refused with a 409 when the revision is stale — the body is an
12
+ * {@link EventConflict} with the event as it now is.
13
+ */
14
+ save(id: number, input: EventSave): Promise<EventDetail>;
15
+ /** Throw away what is waiting and keep what the site is showing. */
16
+ discard(id: number): Promise<EventDetail>;
17
+ /**
18
+ * A copy as a draft that was never published: every field, the categories and the services,
19
+ * the same title and an address with the next free suffix (decision 9). The answer is the
20
+ * copy's form, so the editor can open it straight away.
21
+ */
22
+ duplicate(id: number): Promise<EventDetail>;
23
+ publish(id: number): Promise<EventRow>;
24
+ unpublish(id: number): Promise<EventRow>;
25
+ remove(id: number): Promise<void>;
26
+ restore(id: number): Promise<EventRow>;
27
+ /** The publications, newest first. */
28
+ versions(id: number): Promise<EventVersion[]>;
29
+ /** An old publication becomes the draft; putting it on the site is a separate step. */
30
+ restoreVersion(id: number, number: number): Promise<EventDetail>;
31
+ }
32
+ /** The path of the list under the panel's API. */
33
+ export declare const EVENTS_API = "events";
34
+ /**
35
+ * Everything under `/events`, below the panel's API path (§4.10) — except the categories, which
36
+ * are the panel's shared category API under `events/categories`.
37
+ */
38
+ export declare function createEventsApi(admin: AdminContext): EventsApi;
package/dist/days.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { ScreenModel } from '@webx-ui/schema';
2
+ /**
3
+ * The same wall clock in the reader's own zone: `2026-10-12T00:00:00+08:00` read in New York
4
+ * becomes `2026-10-12T00:00:00-04:00`.
5
+ *
6
+ * For an event of days the server keeps whole days in its own zone (§4.10) — midnight of the
7
+ * first, `23:59:59` of the last — and the moment is not the point, the calendar date is. A date
8
+ * picker reads a moment, though, and midnight at +08:00 is still the day before in New York, while
9
+ * `23:59:59` in UTC is already the day after at +08:00: the same event would show a different
10
+ * first or last day in every browser that is not in the site's zone. Moved onto the reader's
11
+ * clock, the picker shows the day the server named, and a save sends it back with the reader's
12
+ * offset — which the server cuts to a day in that same offset (`Moment::day()`), so it stays
13
+ * the same day both ways.
14
+ *
15
+ * Anything that is not such a string comes back as it was.
16
+ */
17
+ export declare function onReadersClock(value: unknown): unknown;
18
+ /** The values of `events.form` with the days of an event of days put on the reader's clock. */
19
+ export declare function withDaysAsWritten(values: ScreenModel): ScreenModel;
@@ -0,0 +1,19 @@
1
+ import { InjectionKey, Ref } from 'vue';
2
+ import { EventRow } from './types';
3
+ /**
4
+ * What the editor knows and the nodes of `events.form` do not: the event being edited, and a way
5
+ * to read it again. The history needs both — its list is keyed by the event, and a restored
6
+ * version has to reach the fields the form is bound to.
7
+ */
8
+ export interface EventEditorContext {
9
+ /** The event as the server last answered it, or `null` while the first request is out. */
10
+ event: Ref<EventRow | null>;
11
+ /** Whether this administrator may write at all. */
12
+ canManage: boolean;
13
+ /** Ask the server for the event again — after a restore, a publication, a discard. */
14
+ reload(): Promise<void>;
15
+ }
16
+ export declare const eventEditorKey: InjectionKey<EventEditorContext>;
17
+ export declare function provideEventEditor(editor: EventEditorContext): void;
18
+ /** The editor above this node, or `null` outside one — a demo or a test draws nothing. */
19
+ export declare function useEventEditor(): EventEditorContext | null;
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ /** Puts this package's English under the panel's dictionary, once per panel. */
2
+ export declare function useEventsMessages(): void;
@@ -0,0 +1,9 @@
1
+ export { events, eventCategoriesOptions, type EventsOptions } from './module';
2
+ export { createEventsApi, EVENTS_API, type EventsApi } from './api';
3
+ export { eventsMessages } from './messages';
4
+ export { provideEventEditor, eventEditorKey, useEventEditor, type EventEditorContext, } from './editor';
5
+ export { default as WxEventsPage } from './EventsPage';
6
+ export { default as WxEventCreateDialog } from './EventCreateDialog';
7
+ export { default as WxEventEditorPage } from './EventEditorPage';
8
+ export { default as WxEventHistory } from './EventHistory';
9
+ export type { EventConflict, EventDetail, EventInput, EventQuery, EventRow, EventSave, EventsPage, EventStatus, EventTermRef, EventVersion, EventWhen, } from './types';