ਇਸ ਗਾਈਡ ਵਿੱਚ ਮੀਟਿੰਗ ਵਾਲੇ ਕਮਰੇ ਬੁੱਕ ਕਰਨ ਲਈ ਇੱਕ ਕੈਲੰਡਰ ਬਣਾਇਆ ਗਿਆ ਹੈ: ਹਰ ਕਮਰੇ ਦੀ ਇੱਕ ਕਤਾਰ ਵਾਲੀ ਟਾਈਮਲਾਈਨ, ਡ੍ਰੈਗ ਕਰਕੇ ਸਹੀ ਥਾਂ ’ਤੇ ਰੱਖੀਆਂ ਜਾਣ ਵਾਲੀਆਂ ਬੁਕਿੰਗਾਂ, ਕਿਸੇ ਕਮਰੇ ਦੀ ਦੋਹਰੀ ਬੁਕਿੰਗ ਰੋਕਣ ਵਾਲਾ ਨਿਯਮ, ਅਤੇ ਬੁਕਿੰਗ ਨੂੰ ਕਿਸੇ ਵੀ ਕੈਲੰਡਰ ਵਿੱਚ ਜੋੜਨ ਵਾਲੀ ਫ਼ਾਈਲ। ਇਸ ਵਿੱਚ @needless-ui/angular ਦਾ ਸ਼ਡਿਊਲਰ ਵਰਤਿਆ ਗਿਆ ਹੈ, ਜੋ ਬਾਕੀ Needless UI ਵਾਂਗ MIT ਲਾਇਸੰਸ ਅਧੀਨ ਹੈ, ਇਸ ਲਈ ਰਿਸੋਰਸ ਟਾਈਮਲਾਈਨ ਕਿਸੇ ਵੀ ਐਪ ਲਈ ਮੁਫ਼ਤ ਹੈ।
ਕਮਰੇ ਅਤੇ ਬੁਕਿੰਗਾਂ
ਕਮਰੇ ਰਿਸੋਰਸ ਹਨ: ਇੱਕ id, ਇੱਕ title, ਅਤੇ ਬਾਕੀ ਸਭ ਕੁਝ data ਵਿੱਚ। ਬੁਕਿੰਗਾਂ ਸਾਦੇ ISO ਸਮਿਆਂ ਵਾਲੇ ਇਵੈਂਟ ਹਨ, ਜਿਵੇਂ 2026-10-23T09:00, ਅਤੇ ਉਨ੍ਹਾਂ ਦੇ ਕਮਰੇ ਦੀ id resource ਵਿੱਚ ਹੁੰਦੀ ਹੈ। ਇੱਕ ਬੁਕਿੰਗ ਵਿੱਚ ਸੂਚੀ ਦੇ ਰੂਪ ਵਿੱਚ ਕਈ ਕਮਰੇ, ਜਾਂ ਲੋਕ, ਵੀ ਹੋ ਸਕਦੇ ਹਨ।
ਹਰ ਕਮਰੇ ਦੀ ਇੱਕ ਕਤਾਰ
ਦੋਵਾਂ ਨੂੰ view="timeline" ਨਾਲ nui-scheduler ਵਿੱਚ ਪਾਸ ਕਰੋ। dayStart ਅਤੇ dayEnd ਦਿਨ ਦੇ ਸਿਰਫ਼ ਉਹ ਘੰਟੇ ਦਿਖਾਉਂਦੇ ਹਨ ਜਦੋਂ ਕਮਰੇ ਖੁੱਲ੍ਹੇ ਹੁੰਦੇ ਹਨ, snapMinutes ਬੁਕਿੰਗਾਂ ਨੂੰ 15-15 ਮਿੰਟ ਹਿਲਾਉਂਦਾ ਹੈ, ਅਤੇ businessHours ਉਸ ਸਮੇਂ ’ਤੇ ਛਾਂ ਪਾਉਂਦੇ ਹਨ ਜਦੋਂ ਕਮਰੇ ਬੰਦ ਹੁੰਦੇ ਹਨ। nuiSchedulerResource ਹਰ ਕਤਾਰ ਦਾ ਹੈਡਰ ਬਣਾਉਂਦਾ ਹੈ।
<nui-scheduler
[events]="bookings()"
[resources]="rooms"
view="timeline"
dayStart="8"
dayEnd="19"
snapMinutes="15"
[businessHours]="hours"
editable
selectable
[allow]="free"
(slotSelect)="book($event)"
(eventChange)="move($event)"
(rangeChange)="range.set($event)"
>
<ng-template nuiSchedulerResource let-room>{{ room.title }}</ng-template>
</nui-scheduler>
<button nuiButton type="button" (click)="download()">Add to calendar</button>ਬੁੱਕ ਕਰੋ ਅਤੇ ਹਿਲਾਓ
ਸ਼ਡਿਊਲਰ ਤੁਹਾਡਾ ਡਾਟਾ ਆਪ ਕਦੇ ਨਹੀਂ ਬਦਲਦਾ: ਇਹ ਸਿਰਫ਼ ਦੱਸਦਾ ਹੈ ਕਿ ਲੋਕ ਕੀ ਕਰਦੇ ਹਨ। ਕਿਸੇ ਕਮਰੇ ਦੀ ਕਤਾਰ ’ਤੇ ਡ੍ਰੈਗ ਕਰਨ ਨਾਲ ਸਮਾਂ ਚੁਣਿਆ ਜਾਂਦਾ ਹੈ, ਅਤੇ slotSelect ਉਸ ਨੂੰ ਕਮਰੇ ਸਮੇਤ ਦੱਸਦਾ ਹੈ। ਕਿਸੇ ਬੁਕਿੰਗ ਨੂੰ, ਜਾਂ ਉਸ ਦੇ ਅੰਤ ਨੂੰ, ਡ੍ਰੈਗ ਕਰਨ ’ਤੇ eventChange ਉਸ ਦਾ ਨਵਾਂ ਸਮਾਂ ਦੱਸਦਾ ਹੈ, ਅਤੇ ਜੇ ਉਹ ਦੂਜੇ ਕਮਰੇ ਵਿੱਚ ਗਈ ਹੋਵੇ ਤਾਂ ਉਸ ਦਾ ਨਵਾਂ ਕਮਰਾ ਵੀ। ਸਿਗਨਲ ਅੱਪਡੇਟ ਕਰੋ, ਅਤੇ ਟਾਈਮਲਾਈਨ ਵੀ ਉਸੇ ਮੁਤਾਬਕ ਬਦਲ ਜਾਂਦੀ ਹੈ।
import { Component, signal } from '@angular/core';
import { NuiButton } from '@needless-ui/angular/button';
import {
NuiScheduler,
type NuiSchedulerChange,
type NuiSchedulerEvent,
NuiSchedulerResourceTemplate,
type NuiSchedulerSlot,
} from '@needless-ui/angular/scheduler';
import { downloadIcs } from './booking-ics';
@Component({
selector: 'app-bookings',
imports: [NuiButton, NuiScheduler, NuiSchedulerResourceTemplate],
templateUrl: './booking.html',
})
export class Bookings {
/** Rooms are resources; bookings are events, with their room in `resource`. */
protected readonly rooms = [
{ id: 'atlas', title: 'Atlas' },
{ id: 'boreal', title: 'Boreal' },
];
protected readonly bookings = signal<NuiSchedulerEvent[]>([]);
/** Open on weekdays from 8:00 to 19:00: other time is shaded. */
protected readonly hours = [{ days: [1, 2, 3, 4, 5], start: '08:00', end: '19:00' }];
/** The days on screen: load their bookings when it changes. */
protected readonly range = signal<{ start: string; end: string } | null>(null);
protected book({ start, end, resource }: NuiSchedulerSlot): void {
const booking = { id: crypto.randomUUID(), title: 'New booking', start, end, resource };
this.bookings.update((all) => [...all, booking]);
}
protected move({ event, start, end, resource }: NuiSchedulerChange): void {
this.bookings.update((all) =>
all.map((b) =>
b.id === event.id ? { ...b, start, end, resource: resource ?? b.resource } : b,
),
);
}
/** A room holds one booking at a time. */
protected readonly free = (time: NuiSchedulerChange | NuiSchedulerSlot): boolean => {
const id = 'event' in time ? time.event.id : null;
const room = 'event' in time ? (time.resource ?? time.event.resource) : time.resource;
return !this.bookings().some(
(b) => b.id !== id && b.resource === room && b.start < time.end && b.end > time.start,
);
};
protected download(): void {
downloadIcs(this.bookings(), 'bookings');
}
}ਕੋਈ ਦੋਹਰੀ ਬੁਕਿੰਗ ਨਹੀਂ
ਕੋਈ ਬੁਕਿੰਗ ਬਣਨ ਜਾਂ ਹਿੱਲਣ ਤੋਂ ਪਹਿਲਾਂ allow ਤੋਂ ਪੁੱਛਿਆ ਜਾਂਦਾ ਹੈ। ਜਦੋਂ ਇਹ false ਵਾਪਸ ਕਰਦਾ ਹੈ, ਤਾਂ ਡ੍ਰੈਗ ਲਾਲ ਦਿਸਦਾ ਹੈ ਅਤੇ ਛੱਡਣ ’ਤੇ ਕੁਝ ਨਹੀਂ ਹੁੰਦਾ, ਅਤੇ ਕੀ-ਬੋਰਡ ਨਾਲ ਕੋਸ਼ਿਸ਼ ਕਰਨ ’ਤੇ ਸ਼ਡਿਊਲਰ ਦੱਸਦਾ ਹੈ ਕਿ ਇਹ ਸਮਾਂ ਉਪਲਬਧ ਨਹੀਂ। ਉਦਾਹਰਨ ਕਮਰੇ ਦੀਆਂ ਬਾਕੀ ਬੁਕਿੰਗਾਂ ਜਾਂਚਦੀ ਹੈ; ਆਪਣੇ ਸਰਵਰ ’ਤੇ ਦੁਬਾਰਾ ਜਾਂਚੋ, ਕਿਉਂਕਿ ਆਖ਼ਰੀ ਫ਼ੈਸਲਾ ਉਸੇ ਦਾ ਹੁੰਦਾ ਹੈ।
ਸਕ੍ਰੀਨ ’ਤੇ ਦਿਸਦੇ ਦਿਨ ਲੋਡ ਕਰੋ
rangeChange ਦਿਖਾਏ ਗਏ ਪਹਿਲੇ ਅਤੇ ਆਖ਼ਰੀ ਦਿਨ ਦੱਸਦਾ ਹੈ, ਇੱਕ ਵਾਰ ਸ਼ੁਰੂ ਵਿੱਚ ਅਤੇ ਫਿਰ ਜਦੋਂ ਵੀ ਲੋਕ ਪੰਨਾ ਬਦਲਦੇ ਹਨ, ਤਾਂ ਜੋ ਤੁਸੀਂ ਸਿਰਫ਼ ਉਨ੍ਹਾਂ ਦਿਨਾਂ ਦੀਆਂ ਬੁਕਿੰਗਾਂ ਲਿਆ ਸਕੋ, httpResource ਨਾਲ ਜਾਂ ਆਪਣੀ ਪਸੰਦ ਦੀ ਕਿਸੇ ਵੀ ਰਿਕੁਐਸਟ ਨਾਲ।
ਕੈਲੰਡਰ ਵਿੱਚ ਜੋੜੋ
nuiSchedulerToIcs() ਬੁਕਿੰਗਾਂ ਨੂੰ iCalendar ਫ਼ਾਈਲ ਵਜੋਂ ਲਿਖਦਾ ਹੈ, ਜਿਸ ਨੂੰ Google Calendar, Outlook ਅਤੇ Apple Calendar ਇੰਪੋਰਟ ਕਰਦੇ ਹਨ। nuiSchedulerFromIcs() ਅਜਿਹੀ ਫ਼ਾਈਲ ਵਾਪਸ ਪੜ੍ਹਦਾ ਹੈ, ਅਤੇ ਦੂਜੇ ਟਾਈਮ ਜ਼ੋਨਾਂ ਦੇ ਸਮਿਆਂ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦੇ ਆਪਣੇ ਟਾਈਮ ਜ਼ੋਨ ਵਿੱਚ ਲੈ ਆਉਂਦਾ ਹੈ।
import { type NuiSchedulerEvent, nuiSchedulerToIcs } from '@needless-ui/angular/scheduler';
/** Saves events as an .ics file, which Google Calendar, Outlook and Apple Calendar import. */
export function downloadIcs(events: readonly NuiSchedulerEvent[], name: string): void {
const file = new Blob([nuiSchedulerToIcs(events, { name })], { type: 'text/calendar' });
const link = document.createElement('a');
link.href = URL.createObjectURL(file);
link.download = `${name}.ics`;
link.click();
URL.revokeObjectURL(link.href);
}ਕੀ-ਬੋਰਡ ਅਤੇ ਸਕ੍ਰੀਨ ਰੀਡਰ
ਇਹ ਸਭ ਮਾਊਸ ਤੋਂ ਬਿਨਾਂ ਵੀ ਕੰਮ ਕਰਦਾ ਹੈ। ਟਾਈਮਲਾਈਨ ਇੱਕੋ ਟੈਬ ਸਟਾਪ ਹੈ: ਐਰੋ ਕੁੰਜੀਆਂ ਸਮਿਆਂ ਅਤੇ ਕਮਰਿਆਂ ਵਿਚਕਾਰ ਲੈ ਜਾਂਦੀਆਂ ਹਨ, Shift ਨਾਲ ਐਰੋ ਸਮਾਂ ਚੁਣਦੇ ਹਨ, ਅਤੇ Enter ਉਸ ਨੂੰ ਬੁੱਕ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਬੁਕਿੰਗ ’ਤੇ, Alt ਨਾਲ ਐਰੋ ਉਸ ਨੂੰ ਕਿਸੇ ਹੋਰ ਸਮੇਂ ਜਾਂ ਕਮਰੇ ਵਿੱਚ ਲੈ ਜਾਂਦੇ ਹਨ। ਹਰ ਬੁਕਿੰਗ ਇੱਕ ਬਟਨ ਹੈ, ਜਿਸ ਦਾ ਨਾਮ ਉਸ ਦਾ ਸਿਰਲੇਖ, ਕਮਰਾ, ਦਿਨ ਅਤੇ ਸਮਾਂ ਹੈ।
ਦਿਨ ਵਿਊ ਵਿੱਚ ਨਾਲ-ਨਾਲ ਕਮਰਿਆਂ, ਵਾਰ-ਵਾਰ ਹੋਣ ਵਾਲੀਆਂ ਬੁਕਿੰਗਾਂ ਅਤੇ ਬਾਕੀ ਸਾਰੇ ਵਿਕਲਪਾਂ ਲਈ ਸ਼ਡਿਊਲਰ ਦਾ ਪੰਨਾ ਅਤੇ ਉਸ ਦਾ API ਵੇਖੋ।