Es Calendar zeigt Dataverse-Termine an, so wie Outlook – Aufgaben und jede andere Tabelle, die der Server registriert – nach Tag, Arbeitswoche, Woche oder Monat oder als Wochenliste. Die Symbolleiste wechselt zwischen Bereichen und Layouts, ein geschäftiger Tag fällt in + mehr zusammen, und Termine liegen gleichzeitig nebeneinander. Es liest die Zeilen des Bereichs auf dem Bildschirm, während du hingehst, über dieselbe Abfrage und Sicherheit wie ein Raster, und zeigt ihre Tage und Zeiten in der Zeitzone des Nutzers an, da jedes Datum im Portal angezeigt wird. Es wird als Zusatzpaket auf jedem Stack geliefert, gezeichnet in deinem Fluent-UI-Thema.
<Calendar regarding={{ tableName: 'account', id: accountId }} /><Calendar Regarding="@(new TableRecordReference("account", accountId))" />Die Termine über Schmeler und Söhne, das Konto, das die Konto-Detailseite Demo zeigt. Regarding Behält den Kalender zu den Terminen über einen einzigen Datensatz.
Ohne Regarding, zeigt der Kalender jede Zeile der angezeigten Tabellen an, die der Benutzer lesen kann. Er liest die Tabellen, die der Server für Kalender registriert – Notizen und jede Aktivitätstabelle sowie alle anderen registrierten ForCalendars Tabellen – jede mit einer eigenen Spalte datiert: einen Termin nach Anfang und Ende, eine Aufgabe, einen Telefonanruf, einen Brief oder ein Fax bis zum Fälligkeitstermin. Termine und Aufgaben werden zunächst angezeigt; die anderen, die der Benutzer lesen kann, werden im Anzeigen-Menü der Toolbar ausgeschaltet angezeigt. DefaultTables (Reagieren: defaultTables) wählt die zuerst angezeigten aus, und Tables (Reagieren: tables) die, die überhaupt angezeigt werden darf. Der Kalender fügt seinen Bereich und den betreffenden Datensatz als eigene Bedingungen hinzu, sodass eine Ansicht das Anzeigen eingrenzen, aber nie erweitern kann.
<Calendar defaultTables={['appointment', 'task', 'phonecall']} /><Calendar DefaultTables="@(["appointment", "task", "phonecall"])" />Der Kalender listet nur die Termine auf, die der Nutzer lesen darf, und erlaubt es ihnen, nur einen Termin zu verschieben, wo er ihn ändern kann. Ein Portal zeigt den Kontakten in der Regel die Termine, zu denen sie eingeladen sind, RowsInvolvingContact requiredattendees und optionalattendees liest sie durch die Partylisten des Termins, ohne sie zu den eigenen Terminen zu machen.
// Die Kontakte lesen die Termine, zu denen sie eingeladen sind, entweder als Pflicht- oder als freiwilliger Teilnehmer.
builder.Services.AddTableAccess("appointment", t => t
.ForSignedInUsers()
.RowsInvolvingContact("requiredattendees", "optionalattendees")
.Allow(TableSecurityPermission.Read)
.ReadingAllColumns());
// Jeder Termin, den der Nutzer lesen kann, erreicht das Portal: Eine Einladung sagt schon, dass es für ihn ist.
builder.Services.Configure<SecurityOptions>(options =>
options.PortalVisibility.UnfilteredActivities.Add("appointment"));
Wie bei anderen Aktivitäten erreicht ein Termin das Portal nur, wenn seine Beschreibung mit *WEB*beginnt, es sei denn, seine Tabelle befindet sich in SecurityOptions.PortalVisibility.UnfilteredActivities. Ein Kalenderportal fügt dort hinzu appointment , wie oben beschrieben, sodass Mitarbeiter wie immer Termine in Dynamics und Outlook buchen.
Der Anwendungsbenutzer des Portals benötigt auch Read-on-Termine in Dataverse. Dataverse gewährt jedem Aktivitätstyp durch eine bestimmte Berechtigung, sodass Termine durch die Read-On-Aktivitäten abgedeckt werden, die die Power Portals Pro Application User-Rolle bereits umfasst.
Ein Auftreten eines wiederkehrenden Termins wird wie bei jedem anderen Termin angezeigt, mit dem Wiederholungssymbol neben dem Befragten. Ein Klick auf einen Termin fragt, ob dieses Ereignis oder die ganze Serie geöffnet werden soll; das Verschieben oder Anpassen eines Termins ändert allein dieses Ereignis. Der Kalender zeigt die Vorkommnisse an, die Dataverse geschrieben hat: Dataverse schreibt die einer Serie im Voraus, bis zum Erweiterungsfenster der Umgebung – standardmäßig zwölf Monate – und die späteren im Laufe der Zeit, sodass eine Serie, die nie endet, ein Jahr an Ereignissen gleichzeitig anzeigt.
Ein Termin wird dadurch gezeichnet, wie er seine Zeit anzeigt, wie Outlook ihn zeichnet: beschäftigt wie ein Farbton mit einer Bar daneben, frei mit der Bar allein, vorsichtig gestreift und nicht im Büro in Lila, gelesen aus dem Statusgrund. Ein abgeschlossener Termin zeigt sich als beschäftigt, ein abgesagter als kostenlos mit durchgestrichenem Thema. In einem Monat, in dem ein Termin mit einer Uhrzeit ein Punkt daneben ist und in den Reihen der Tagesordnung sichtbar ist, zeigt nur die Farbe. Die von dir bereitgestellten Termine nehmen ShowAs und (Reagieren: showAs und canceled), und jeder wird mit einer Klasse gezeichnet – ppp-calendar-appointment-free, -busy, -tentative, und -out-of-office -canceled – um ihn neu zu Canceled gestalten.
In einem Editable Kalender, der eigene Termine lädt, öffnet die Auswahl einer Zeit einen neuen Termin darüber, über den Regarding Datensatz, und ein Klick auf einen Termin öffnet dessen Details als Formular, das mit derselben Tabelle-, Zeilen- und Spaltensicherheit wie jeder Datensatz gespeichert ist. Das Verschieben oder Anpassen einer Zeile speichert sie – ihren Start, ihr Ende und ob es ganze Tage dauert – wobei der Benutzer die Zeile und diese Spalten ändern kann und sie nicht abgeschlossen, abgebrochen oder inaktiv ist; eine Zeile, deren Tabelle ein Datum beibehält, wie zum Beispiel das Fälligkeitsdatum einer Aufgabe, wird verschoben, ändert sich aber nicht in der Größe, und eine, die nach dem Zeitpunkt der Erstellung datiert ist, bleibt bestehen. Das Klicken auf eine Zeile einer anderen Tabelle öffnet ihr Formular: die Spalten, die die Registrierung anzeigt, oder Ihr eigenes Formular für die Tabelle, innerhalb des Kalenders MultiTableForm (React: forms). Die Details eines Termins und das Formular einer anderen Tabelle öffnen sich in einem Dialog in der Mitte oder, mit FormLocation (React: formLocation), in einem Seitenfeld links oder rechts. Die Teilnehmer werden mit PartyListEditbearbeitet, was ColumnEdit auch für jede Parteiliste verwendet wird – darunter eine E-Mail-Adresse To, From und CC. Während der Benutzer tippt, schlägt er die Kontakte, Konten und Nutzer vor, die er lesen und verlinken kann (Read and Append To), die eine E-Mail-Adresse haben, eine Tabelle ohne beides nie durchsucht; wenn man einen auswählt, wird er als Chip hinzugefügt. Wo die Umgebung Nachrichten an unbeantwortete E-Mail-Empfänger erlaubt – oder AllowUnresolvedEmailAddresses es so sagt –, wird eine E-Mail-Adresse, die keinem Datensatz entspricht, von selbst mit Enter hinzugefügt. Ein Termin's Regarding bietet die Tabellen, auf deren Datensätze der Nutzer lesen und verlinken kann; RegardingTables (React: regardingTables) schränkt sie auf die von dir genannten Termine ein. Handle OnRangeSelect stattdessen so, dass Termine auf eigene Weise erstellt werden, und SaveChange (React: onAppointmentChange) zum Speichern bewegt sich auf deine eigene Weise.
<Calendar regarding={account} editable regardingTables={['account', 'contact']} />
{/* Anywhere a party list is edited */}
<PartyListEdit columnName="to" allowUnresolvedEmailAddresses /><Calendar Regarding="@account"
Editable="true"
RegardingTables="@(["account", "contact"])" />
<!-- Anywhere a party list is edited -->
<PartyListEdit ColumnName="to" AllowUnresolvedEmailAddresses="true" />In einem Editable Kalender bietet das Terminformular Wiederholung: täglich oder an Wochentagen, an Wochentagen, monatlich oder jährlich – am Datum oder am Wochentag, wie zum Beispiel am zweiten Dienstag – alle Male und endend nie, nach mehreren Zeiten oder an einem Datum. Dataverse legt die Vorkommnisse in der Zeitzone des Nutzers an, sodass ein Meeting um zehn Uhr bei zehn über eine Uhrenänderung hinweg bleibt. Eine Serie öffnet sich als eigenständige Form, bei der die Wiederholungen geändert werden können, und das Löschen eines Vorkommens bietet das Löschen oder die gesamte Serie an. Wiederholung wird Nutzern angeboten, die Datensätze erstellen recurringappointmentmaster können – und für einen bereits existierenden Termin ihn ändern und löschen, da er zur Serie wird. Gewähren Sie die Serie bei der Erteilung von Terminen und geben Sie der Anwendung des Portals Lesen auf Verbindung in Dataverse: Einen Termin in einer Serie zu machen, liest die Verbindungen, und Dataverse lehnt den Speicherstand ohne diese ab.
// Eine Serie ist eine Aufzeichnung ihrer eigenen Tabelle; ihre Vorkommnisse sind Ernennungen.
builder.Services.AddTableAccess("recurringappointmentmaster", t => t
.ForSignedInUsers()
.RowsOwnedByContact("requiredattendees")
.Allow(TableSecurityPermission.Read | TableSecurityPermission.Create
| TableSecurityPermission.Write | TableSecurityPermission.Delete)
.ReadingAllColumns()
.WritingAllColumns());
builder.Services.Configure<SecurityOptions>(options =>
options.PortalVisibility.UnfilteredActivities.Add("recurringappointmentmaster"));
Ein neuer Termin oder eine Änderung an einem solchen wird in derselben Transaktion wie der Rest seines Speicherstands zu einer Serie: Der Speicherstand sendet einen AddRecurrenceRequest neben den eigenen Termin, sodass der Termin nie ohne seine Serie gespeichert wird, noch die Serie ohne sie. Dataverse erstellt die Serie aus dem Termin mit seinen Teilnehmern und entfernt den Termin. Eine Seite, die ihr eigenes Formular erstellt, kann die Anfrage auf die gleiche Weise senden.
Eine Serie, die sich seit ihrem nächsten Ereignis verändert hat, wie in Outlook: Dataverse, behält die beendeten Ereignisse als eigene Serie und teilt die Serien, groupidsodass sie so bleiben, wie sie stattgefunden haben. Die Zählung, nach der eine Serie endet, umfasst die gesamte Serie – das Portal liest und speichert sie mit den bereits gespeicherten Vorkommnissen – und eine Serie, in der keine mehr zu kommen sind, kann nicht mehr geändert werden. Das Wechseln Der ganze Tag passt zu den Zeiten: an, die ganzen Tage, an denen sie fallen; aus, neun Uhr am ersten von ihnen für eine halbe Stunde. Dataverse hält einen ganztägigen Termin als Tag; das Portal zeigt ihn an und speichert ihn am eigenen Tag des Nutzers, unabhängig von seiner Zeitzone.
Pass stattdessenAppointments, und der Kalender zeigt diese an, anstatt Dataverse zu lesen. Mit on können Termine durch Auswahl eines Bereichs verschoben, verkleinert und erstellt werden: SaveChange (React: onAppointmentChange) speichert einen Move, und False zurück setzt den Termin Editable zurück; OnRangeSelect erhält einen ausgewählten Bereich und OnAppointmentClick einen offenen Termin.
<Calendar appointments={appointments}
editable
onAppointmentChange={saveMove}
onAppointmentClick={openAppointment} /><Calendar Appointments="appointments"
Editable="true"
SaveChange="SaveMoveAsync"
OnAppointmentClick="OpenAppointment" />Wenn der Zeiger auf einen Termin gelegt wird, zeigt man den Besuch, wann und wo er sich befindet, und ein Klick öffnet einen Dialog mit seinen Details, die aus Dataverse gelesen werden, während eine Datensatzseite einen Datensatz liest – über denselben Tabellenzugriff und dieselbe Spaltensicherheit – und wird als nur lesbar angezeigt. Handle OnAppointmentClick (React: onAppointmentClick) um etwas anderes bei einem Klick zu tun, wie zum Beispiel eine eigene Seite zu öffnen. Die Zeilen des Kalenders, seine Tooltips und der Detaildialog können jeweils auf eigene Weise gezeichnet werden: siehe Benutzerdefinierte Darstellung.
Fügen Sie Ihre eigenen Steuerungen in die Symbolleiste mit ToolbarItems (React: die Kinder des Kalenders) vor das Suchfeld, wie es die Tasten in der Gitterleiste sind. A CalendarButton erhält den Kalender beim Klicken: den angezeigten Zeitraum, den Datensatz, um den es geht, und RefreshAsync CreateAppointmentAsync und (React: createAppointment und refresh). NewAppointmentCalendarButton Start einen neuen Termin wie die Auswahl einer Uhrzeit – ab der nächsten halben Stunde, wenn der angezeigte Zeitraum heute umfasst, und ansonsten ab 8:00 Uhr am ersten Tag – und wird nur dort angezeigt, wo etwas beginnt: ein Editable Kalender, dessen Host verwaltet OnRangeSelectoder der eigene Termine für einen Benutzer lädt, der sie erstellen kann.
<Calendar regarding={account} editable>
<NewAppointmentCalendarButton />
{/* Dein eigener Button, den Kalender in die Hand gereicht, wenn du darauf klickst */}
<CalendarButton
label="Export"
icon={<ArrowDownloadRegular />}
onClick={(calendar) => exportAsync(calendar.start, calendar.end)}
/>
</Calendar><Calendar Regarding="@account" Editable="true">
<ToolbarItems>
<NewAppointmentCalendarButton />
<!-- Dein eigener Button, den Kalender in die Hand gereicht, wenn du darauf klickst -->
<CalendarButton Label="Export"
Icon="@(new Icons.Regular.Size20.ArrowDownload())"
OnClick="@((CalendarContext calendar) => ExportAsync(calendar.Start, calendar.End))" />
</ToolbarItems>
</Calendar>Der Kalender ordnet seine Termine nach den Stunden eines Tages, einer Arbeitswoche oder einer Woche, als Monat der Tage oder als Agenda-Liste auf, und seine Werkzeugleiste hat einen Picker, um zwischen ihnen zu wechseln. DefaultLayout (Reagieren: defaultLayout) ist der, in dem er geöffnet wird, eine Woche, es sei denn, du wählst einen anderen. Layouts (Reagieren: layouts) behält ihn bei den von dir benannten, in deiner Reihenfolge aufgelistet: Nenne einen, und der Picker geht und der Kalender bleibt darin. Jedes Layout hat eine eigene Seite: Tag, Arbeitswoche, Woche, Monat und Agenda.
<Calendar defaultLayout="month" layouts={['month', 'agenda']} /><Calendar DefaultLayout="CalendarLayout.Month"
Layouts="@([CalendarLayout.Month, CalendarLayout.Agenda])" />Bieten Sie Ansichten in ViewIds — Dataverse-Ansichten, jede eigene Tabelle — MultiTableViewIds, Ansichten mehrerer Tabellen, die bei AddMultiTableView Dataverse registriert sind oder dort gespeichert sind, sowie CustomViewDefinitions, Ansichten, die im Code definiert sind, und die Werkzeugleiste hat einen Picker, um auszuwählen, was der Kalender anzeigt. DefaultViewId ist der, auf dem sie geöffnet wird. Das Suchfeld findet die Suchspalten jeder Tabelle, wie es die Suche eines Rasters tut. Schalten Sie es mit AllowSearchaus.
Mit AllowFiltering, bietet das Filtermenü der Werkzeugleiste Bearbeiten-Filter, die die Filter der gezeigten Tabellen öffnen, für jede einen Tab in Reihenfolge ihres Namens, jedes Dialogfenster öffnet der Filter-Button eines Rasters: Bedingungen auf den Spalten der Tabelle, verschachtelt in Gruppen, und verwandte Tabellen zum Filtern, über die Spalten und Tabellen, die der Benutzer lesen kann. Die Spalten eines Tabs werden gelesen, wenn er erstmals geöffnet wird. Die Filter ersetzen die eigenen Ansichten, bis der Benutzer eine andere Ansicht auswählt. Sie ist standardmäßig deaktiviert, da der Benutzer alle Filter der Ansicht entfernen kann.
Mit (React: allowSavedViews), kann ein angemeldeter Nutzer das, was der Kalender zeigt – die Ansicht, seinen Filter, die angezeigten AllowSavedViews Tabellen und das Layout – als eigene Ansicht speichern, seine Standardansicht auswählen und die nicht verwendeten Ansichten im Filtermenü der Werkzeugleiste ausblenden. Eine Ansicht nur der Termine wird auf den Rastern der Termine angeboten, ebenso wie eine Ansicht mehrerer Tabellen auf Timelines. Wie Ansichten gespeichert, geändert und geteilt werden, finden Sie auf der Seite Gespeicherte Ansichten.
<Calendar viewIds={[allAppointmentsViewId, scheduledViewId]}
defaultViewId={allAppointmentsViewId}
customViewDefinitions={teamsMeetings}
allowFiltering
allowSavedViews /><Calendar ViewIds="@([allAppointmentsViewId, scheduledViewId])"
DefaultViewId="allAppointmentsViewId"
CustomViewDefinitions="teamsMeetings"
AllowFiltering="true"
AllowSavedViews="true" />Schmeler and Sons' Meetings, Aufgaben und Telefonanrufe, über zwei im Code definierte Ansichten: Meetings and tasks, und Still to do – die Aufgaben und Anrufe, die noch nicht erledigt sind, jede Tabelle hat eine eigene Abfrage. Das Filtermenü schaltet jede Tabelle ein und aus, Bearbeiten Filter hat jeweils einen Tab, und ein angemeldeter Besucher kann das, was der Kalender als eigene Ansicht anzeigt, speichern. Eine Aufgabe oder ein Anruf öffnet sich in einem Seitenbereich rechts (FormLocation).
Nenne einen Abfrageparameter in PersistedStateQueryParameter, und der Kalender behält sein Layout, den angezeigten Zeitraum und die dort gewählte Terminansicht, sodass ein erneutes Laden oder ein gemeinsamer Link ihn dort öffnet, wo er gelassen wurde. Worauf er ohnehin geöffnet werden würde, wird ausgelassen – das Datum, während der angezeigte Zeitraum heute einschließt, sodass ein Link zur aktuellen Woche weiterhin heute folgt. Die Suche bleibt auch erhalten, wenn du sie einschaltest IncludeSearchInPersistedState; sie wird standardmäßig weggelassen, da die Suche durch Nutzer sensibel sein kann. Jede Änderung ersetzt den Browserverlauf, sodass Back die Seite verlässt, anstatt jede Woche wieder durchzugehen. Beide Stacks schreiben denselben Wert, sodass ein Link auf dem einen denselben Kalender auf dem anderen öffnet.
<Calendar defaultLayout="month" persistedStateQueryParameter="calendarState" /><Calendar DefaultLayout="CalendarLayout.Month" PersistedStateQueryParameter="calendarState" />Eine im Code definierte Ansicht speichert den Kalender zu den in Teams abgehaltenen Meetings, öffnet auf der Wochenagenda mit einer festgelegten Höhe.
Der Kalender ist ein Add-on: PowerPortalsPro.Web.Blazor.Calendar auf Blazor und @powerportalspro/react-calendar auf React. Füge das Paket neben das eigene Framework hinzu, um es zu verwenden.
npm install @powerportalspro/react-calendardotnet add package PowerPortalsPro.Web.Blazor.CalendarName | Typ | Default | Beschreibung |
|---|---|---|---|
AllowFiltering | bool | False | |
AllowSavedViews | bool | False | |
AllowSearch | bool | True | |
AppointmentDetails | RenderFragment? | ||
Appointments | IReadOnlyList<CalendarAppointment>? | ||
ChildContent | RenderFragment? | ||
CssClass | string? | ||
CustomViewDefinitions | List<MultiTableViewDefinition>? | ||
DefaultLayout | CalendarLayout | Week | |
DefaultTables | IEnumerable<string>? | ||
DefaultViewId | Guid? | ||
Editable | bool | False | |
FormLocation | DialogLocation | Center | |
Height | string | 600px | |
IncludeSearchInPersistedState | bool | False | |
Layouts | IReadOnlyList<CalendarLayout>? | ||
MatchParties | bool? | ||
MultiTableViewIds | IEnumerable<Guid>? | ||
PersistedStateQueryParameter | string? | ||
Regarding | TableRecordReference? | ||
RegardingTables | IReadOnlyList<string>? | ||
SaveChange | Func<CalendarAppointmentChange, Task<bool>>? | ||
SavedViewsKey | string? | ||
Series | MultiTableSeries? | ||
ShowRecordLinks | bool | True | |
SignInUrl | string | Account/Login | |
Tables | IEnumerable<string>? | ||
ToolbarItems | RenderFragment? | ||
TooltipTemplate | RenderFragment<CalendarAppointment>? | ||
ViewIds | IEnumerable<Guid>? | ||
ViewSort | ViewSort | NameAscending |
AllowFilteringAllowSavedViewsAllowSearchAppointmentDetailsAppointmentsChildContentCssClassCustomViewDefinitionsDefaultLayoutDefaultTablesDefaultViewIdEditableFormLocationHeightIncludeSearchInPersistedStateLayoutsMatchPartiesMultiTableViewIdsPersistedStateQueryParameterRegardingRegardingTablesSaveChangeSavedViewsKeySeriesShowRecordLinksSignInUrlTablesToolbarItemsTooltipTemplateViewIdsViewSortName | Typ | Beschreibung |
|---|---|---|
OnAppointmentClick | EventCallback<string> | |
OnRangeSelect | EventCallback<CalendarRangeSelection> |
OnAppointmentClickOnRangeSelectName | Parameter | Typ | Beschreibung |
|---|---|---|---|
CreateAppointmentAsync | DateTimeOffset? start DateTimeOffset? end bool allDay | Task | |
LoadAppointmentsAsync | DateTimeOffset start DateTimeOffset end | Task<IReadOnlyList<CalendarAppointment>> | |
OnAppointmentChangeAsync | CalendarAppointmentChange change | Task<bool> | |
OnAppointmentClickAsync | string id string subject bool recurring string table | Task | |
OnRangeChanged | RangeChanged range | void | |
OnRangeSelectAsync | DateTimeOffset start DateTimeOffset end bool allDay | Task | |
RefreshAsync | Task | ||
RenderTooltip | string id | int |
CreateAppointmentAsyncLoadAppointmentsAsyncOnAppointmentChangeAsyncOnAppointmentClickAsyncOnRangeChangedOnRangeSelectAsyncRefreshAsyncRenderTooltip