Il Calendar affiche les rendez-vous Dataverse comme Outlook — ainsi que les tâches, et toute autre table enregistrée par le serveur — par jour, semaine ouvrée, semaine ou mois, ou sous forme de liste hebdomadaire. Sa barre d’outils passe d’une plage à une autre et d’une mise en page, une journée chargée se replie en + plus, et les rendez-vous se placent côte à côte en même temps. Il lit les lignes de la plage à l’écran au fur et à mesure que vous vous y dirigez, via la même requête et la même sécurité qu’une grille, et affiche leurs jours et heures dans le fuseau horaire de l’utilisateur, chaque date du portail étant affichée. Il est livré sous forme de paquet complémentaire sur chaque pile, dessiné dans votre thème Fluent UI.
<Calendar regarding={{ tableName: 'account', id: accountId }} /><Calendar Regarding="@(new TableRecordReference("account", accountId))" />Les rendez-vous concernant Schmeler and Sons, le compte montré par la démonstration de la page de détail du compte. Regarding Garde le calendrier pour les rendez-vous environ un enregistrement.
Sans Regarding, le calendrier affiche chaque ligne que l’utilisateur peut lire des tableaux qu’il affiche. Il lit les tables que le serveur enregistre pour les calendriers — notes et toutes les tables d’activités, ainsi que toutes celles enregistrées — ForCalendars chacune datée de sa propre colonne : un rendez-vous par son début et sa fin, une tâche, un appel téléphonique, une lettre ou un fax selon sa date d’échéance. Les rendez-vous et tâches s’affichent d’abord ; les autres que l’utilisateur peut lire sont proposées dans le menu Afficher de la barre d’outils, désactivées. DefaultTables (Réagir : defaultTables) choisit celles affichées en premier, et Tables (Réagir : tables) celles qu’il peut afficher en particulier. Le calendrier ajoute sa plage, ainsi que l’enregistrement concernant, comme des conditions à part entière, afin qu’une vue puisse réduire ce qu’elle affiche sans jamais l’élargir.
<Calendar defaultTables={['appointment', 'task', 'phonecall']} /><Calendar DefaultTables="@(["appointment", "task", "phonecall"])" />Le calendrier ne liste que les rendez-vous que l’utilisateur peut lire, et ne lui permet d’en déplacer qu’un seul là où il peut le modifier. Un portail donne généralement aux contacts les rendez-vous auxquels ils sont invités : RowsInvolvingContact on requiredattendees et optionalattendees les lit à travers les listes de parties du rendez-vous, sans en faire les propres à leur contact.
// Les contacts lisent les rendez-vous auxquels ils sont invités, qu’ils soient obligatoires ou optionnels.
builder.Services.AddTableAccess("appointment", t => t
.ForSignedInUsers()
.RowsInvolvingContact("requiredattendees", "optionalattendees")
.Allow(TableSecurityPermission.Read)
.ReadingAllColumns());
// Chaque rendez-vous que l’utilisateur peut lire arrive sur le portail : être invité indique déjà que c’est pour lui.
builder.Services.Configure<SecurityOptions>(options =>
options.PortalVisibility.UnfilteredActivities.Add("appointment"));
Comme pour d’autres activités, un rendez-vous n’arrive au portail que lorsque sa description commence par *WEB*, sauf si son tableau est dans SecurityOptions.PortalVisibility.UnfilteredActivities. Un portail calendrier y ajoute appointment , comme ci-dessus, afin que le personnel prenne des rendez-vous dans Dynamics et Outlook comme toujours.
L’utilisateur de l’application du portail doit également être lu sur les rendez-vous dans Dataverse. Dataverse accorde à chaque type d’activité un seul ensemble de privilèges, de sorte que les rendez-vous sont couverts par les activités de lecture que le rôle d’utilisateur d’application Power Portals Pro détient déjà.
Une occurrence d’un rendez-vous récurrent est affichée comme n’importe quel autre rendez-vous, avec l’icône de répétition à côté de son sujet. Cliquer sur l’un demande s’il faut ouvrir cette occurrence ou toute la série ; déplacer ou redimensionner un événement ne change que cet occurrence. Le calendrier montre les occurrences écrites par Dataverse : Dataverse écrit celles d’une série à l’avance, en ce qui concerne la fenêtre d’extension de l’environnement — douze mois par défaut — et les plus récentes au fil du temps, donc une série qui ne se termine jamais affiche une année d’occurrences à la fois.
Un rendez-vous est tracé selon la façon dont il indique son heure, tel qu’Outlook le dessine : occupé comme une teinte avec une barre à côté, libre avec la barre seule, timidement rayé et hors du bureau en violet, lu à partir de sa raison de statut. Un rendez-vous complété apparaît comme occupé, un rendez-vous annulé comme libre avec son sujet rayé. Dans un mois, où un rendez-vous avec une heure est un point à côté, et dans les rangées de l’ordre du jour, seule la couleur apparaît. Les rendez-vous que vous proposez prennent ShowAs et (Réagir : showAs et canceled), et chacun est tracé avec une classe — ppp-calendar-appointment-free, -busy, -tentative, et -out-of-office -canceled — pour le restyler Canceled .
Dans un Editable calendrier qui charge ses propres rendez-vous, sélectionner une heure ouvre un nouveau rendez-vous au-dessus, à propos de l’enregistrement Regarding , et cliquer sur un rendez-vous ouvre ses détails en tant que formulaire, sauvegardé avec la même sécurité de tableau, ligne et colonne que n’importe quel enregistrement. Déplacer ou redimensionner une ligne la sauve — son début, sa fin et si cela prend des jours entiers — où l’utilisateur peut changer la ligne et ces colonnes sans qu’elle soit complétée, annulée ou inactive ; une ligne dont la table conserve une date, comme la date d’une tâche, bouge mais ne se redimensionne pas, et une rangée daté de sa création reste en place. Cliquer sur une ligne d’une autre table ouvre son formulaire : les colonnes affichées par son enregistrement, ou votre propre formulaire pour la table, à MultiTableForm l’intérieur du calendrier (Réagir : forms). Les détails d’un rendez-vous et celui d’une autre table s’ouvrent dans une boîte de dialogue au centre, ou, avec FormLocation (Réagir : formLocation), dans un panneau latéral à gauche ou à droite. Ses participants sont modifiés avec PartyListEdit, qui ColumnEdit utilise également pour chaque liste de parties — entre autres un e-mail À, De À et en Copie. Au fur et à mesure que l’utilisateur tape, il suggère les contacts, comptes et utilisateurs qu’il peut lire et auxquels ils peuvent faire des liens (Lire et Ajouter) qui ont une adresse e-mail, un tableau sans les deux jamais recherchés ; en choisir un l’ajoute comme une puce. Lorsque l’environnement permet des messages à des destinataires d’emails non résolus — ou AllowUnresolvedEmailAddresses le dit — une adresse e-mail qui ne correspond à aucun enregistrement est ajoutée d’elle-même avec Entrée. Le Concernant d’un rendez-vous propose les tableaux auxquels il peut indiquer dont l’utilisateur peut lire et lier ; RegardingTables (Réagir : regardingTables) les réduit à ceux que vous nommez. Gérez OnRangeSelect pour créer des rendez-vous à votre façon, et SaveChange (Réagir : onAppointmentChange) pour sauvegarder les mouvements à votre façon.
<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" />Dans un Editable calendrier, le formulaire d’un rendez-vous propose Répéter : quotidiennement ou en semaine, les jours de la semaine, mensuel ou annuel — à la date ou en semaine, comme le deuxième mardi — tous les temps et ne se terminant jamais, après plusieurs fois ou à une même date. Dataverse présente les occurrences dans le fuseau horaire de l’utilisateur, donc une réunion à dix heures reste à dix heures à travers un changement d’horloge. Une série s’ouvre comme une forme à part, où la façon dont elle se répète peut être modifiée, et la suppression d’une occurrence propose de la supprimer ou de supprimer toute la série. Répéter est proposé aux utilisateurs qui peuvent créer recurringappointmentmaster des enregistrements — et, pour un rendez-vous déjà existant, le modifier et le supprimer, puisqu’il devient la série. Accordez la série comme vous accordez des rendez-vous, et donnez à l’utilisateur de l’application du portail Lecture sur la connexion dans Dataverse : faire un rendez-vous une série lit ses connexions, et Dataverse refuse la sauvegarde sans cela.
// Une série est un enregistrement de sa propre table ; ses occurrences sont des rendez-vous.
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"));
Un nouveau rendez-vous, ou un changement d’un seul, devient une série dans la même transaction que le reste de sa sauvegarde : la sauvegarde envoie une AddRecurrenceRequest à côté de celle du rendez-vous, donc le rendez-vous n’est jamais sauvegardé sans sa série, ni la série sans elle. Dataverse crée la série à partir du rendez-vous, avec ses participants, et supprime le rendez-vous. Une page qui construit son propre formulaire peut envoyer la demande de la même manière.
Une série qui a commencé change à partir de sa prochaine occurrence, comme dans Outlook : Dataverse conserve les occurrences qui se sont terminées comme une série à part, partageant la groupidsérie , afin qu’elles restent telles qu’elles ont eu lieu. Le compte qu’une série termine est de toute la série — le portail le lit et le sauvegarde avec les occurrences déjà conservées — et une série sans aucun jour ne peut plus être modifiée. Changer toute la journée correspond aux heures : sur les jours entiers sur lesquels ils tombent ; hors service, neuf heures le premier d’entre eux pendant une demi-heure. Dataverse garde un rendez-vous toute la journée comme jour ; le portail l’affiche et l’enregistre le jour de l’utilisateur, quel que soit son fuseau horaire.
Passez Appointments à la place, et le calendrier affiche ceux-ci plutôt que de lire Dataverse. Avec Editable activé, les rendez-vous peuvent être déplacés, redimensionnés et créés en sélectionnant une plage : SaveChange (Réagir : onAppointmentChange) sauvegarde un déplacement, et retourner faux remet le rendez-vous en arrière ; OnRangeSelect reçoit une plage sélectionnée, et OnAppointmentClick un rendez-vous ouvert.
<Calendar appointments={appointments}
editable
onAppointmentChange={saveMove}
onAppointmentClick={openAppointment} /><Calendar Appointments="appointments"
Editable="true"
SaveChange="SaveMoveAsync"
OnAppointmentClick="OpenAppointment" />Reposer le pointeur sur un rendez-vous indique son sujet, quand et où il se trouve, et cliquer sur un ouvre une boîte de dialogue avec ses détails, lu dans Dataverse comme une page d’enregistrement lit un enregistrement — via le même accès à la table et la même sécurité de colonne — et s’affiche en lecture seule. Gérez OnAppointmentClick (Réagir : onAppointmentClick) pour faire autre chose en un clic, comme ouvrir votre propre page. Les lignes du calendrier, ses infobulles et la boîte de dialogue des détails peuvent chacun être dessinés à votre manière : voir Rendu personnalisé.
Placez vos propres contrôles dans la barre d’outils avec ToolbarItems (Réagir : les enfants du calendrier), devant la boîte de recherche, comme les boutons de la barre d’outils d’une grille. A reçoit le calendrier lorsqu’on CalendarButton clique : la période affichée, l’enregistrement dont il s’agit, et RefreshAsync CreateAppointmentAsync (Réagir : createAppointment et refresh). NewAppointmentCalendarButton commence un nouveau rendez-vous comme le fait sélectionner une heure — à partir de la prochaine demi-heure où la période affichée prend en compte aujourd’hui, et sinon à partir de 8h00 le premier jour — et il n’est montré que là où cela commence quelque chose : un Editable calendrier dont l’hôte gère OnRangeSelect, ou qui charge ses propres rendez-vous pour un utilisateur qui peut les créer.
<Calendar regarding={account} editable>
<NewAppointmentCalendarButton />
{/* Votre propre bouton, vous avez donné le calendrier en cliquant */}
<CalendarButton
label="Export"
icon={<ArrowDownloadRegular />}
onClick={(calendar) => exportAsync(calendar.start, calendar.end)}
/>
</Calendar><Calendar Regarding="@account" Editable="true">
<ToolbarItems>
<NewAppointmentCalendarButton />
<!-- Votre propre bouton, vous avez donné le calendrier en cliquant -->
<CalendarButton Label="Export"
Icon="@(new Icons.Regular.Size20.ArrowDownload())"
OnClick="@((CalendarContext calendar) => ExportAsync(calendar.Start, calendar.End))" />
</ToolbarItems>
</Calendar>Le calendrier indique ses rendez-vous par heures d’un jour, d’une semaine de travail ou d’une semaine, comme un mois de jours, ou comme une liste d’agenda, et sa barre d’outils dispose d’un selecteur pour passer d’un à l’autre. DefaultLayout (Réagir : defaultLayout) est celui qu’il ouvre, une semaine sauf si vous en choisissez une autre. Layouts (Réagir : layouts) garde les rendez-vous à ceux que vous nommez, listés dans votre ordre : nommer un, et le sélectionneur part et le calendrier y reste. Chaque mise en page a sa propre page : Jour, Semaine de travail, Semaine, Mois et Agenda.
<Calendar defaultLayout="month" layouts={['month', 'agenda']} /><Calendar DefaultLayout="CalendarLayout.Month"
Layouts="@([CalendarLayout.Month, CalendarLayout.Agenda])" />Offrir des vues dans ViewIds — Vues Dataverse, chacune de ses propres tables — MultiTableViewIds, vues de plusieurs tables enregistrées ou AddMultiTableView conservées dans Dataverse, et CustomViewDefinitions, vues définies dans le code, et la barre d’outils dispose d’un sélecteur pour choisir ce que le calendrier affiche. DefaultViewId est celui sur lequel elle s’ouvre. La boîte de recherche trouve les colonnes de recherche de chaque table, comme le fait la recherche d’une grille. Désactivez-la avec AllowSearch.
Avec AllowFiltering, le menu Filtre de la barre d’outils propose des filtres Modifier, qui ouvrent les filtres des tables affichées, un onglet pour chacun dans l’ordre de son nom, chaque dialogue s’ouvre le bouton Filtre d’une grille : les conditions sur les colonnes de la table, imbriquées en groupes, et les tables associées pour filtrer, au-dessus des colonnes et tableaux que l’utilisateur peut lire. Les colonnes d’un onglet sont lues lors de son ouverture initiale. Les filtres remplacent ceux de la vue jusqu’à ce que l’utilisateur choisisse une autre vue. Il est désactivé par défaut, car l’utilisateur peut supprimer tous les filtres que possède la vue.
Avec AllowSavedViews (Réagir : allowSavedViews), un utilisateur connecté peut enregistrer ce que le calendrier affiche — la vue, son filtre, les tableaux affichés et la mise en page — comme une vue à son nom, choisir sa vue par défaut et masquer celles qu’il n’utilise pas, depuis le menu Filtre de la barre d’outils. Une vue des rendez-vous seule est également proposée sur les grilles des rendez-vous, ainsi qu’une vue de plusieurs tables sur les timelines. La façon dont les vues sont sauvegardés, modifiées et partagées se trouve sur la page Vues Sauvegardées .
<Calendar viewIds={[allAppointmentsViewId, scheduledViewId]}
defaultViewId={allAppointmentsViewId}
customViewDefinitions={teamsMeetings}
allowFiltering
allowSavedViews /><Calendar ViewIds="@([allAppointmentsViewId, scheduledViewId])"
DefaultViewId="allAppointmentsViewId"
CustomViewDefinitions="teamsMeetings"
AllowFiltering="true"
AllowSavedViews="true" />Les réunions, tâches et appels téléphoniques de Schmeler and Sons, à travers deux vues définies en code : Réunions et tâches, et Encore à faire — les tâches et appels non encore terminés, chaque requête de table la sienne. Le menu Filtre active et désactive chaque table, les filtres Modifier ont un onglet pour chacune, et un visiteur connecté peut enregistrer ce que le calendrier affiche comme une vue propre. Une tâche ou un appel s’ouvre dans un panneau latéral à droite (FormLocation).
Nommez un paramètre de requête dans PersistedStateQueryParameter, et le calendrier conserve sa mise en page, la période affichée et la vue rendez-vous choisie là, donc un rechargement ou un lien partagé l’ouvre là où il a été laissé. Ce sur quoi il s’ouvrirait de toute façon est laissé de côté — la date tandis que la période affichée inclut aujourd’hui, donc un lien vers la semaine en cours continue de suivre aujourd’hui. La recherche est aussi conservée lorsque vous activez IncludeSearchInPersistedState; elle est laissée de côté par défaut, car ce que les utilisateurs recherchent peut être sensible. Chaque changement remplace l’historique du navigateur, donc Retour quitte la page plutôt que de revenir en arrière chaque semaine. Les deux piles écrivent la même valeur, donc un lien créé sur l’une ouvre le même calendrier sur l’autre.
<Calendar defaultLayout="month" persistedStateQueryParameter="calendarState" /><Calendar DefaultLayout="CalendarLayout.Month" PersistedStateQueryParameter="calendarState" />Une vue définie par le code maintient le calendrier aux réunions tenues dans Teams, en s’ouvrant à l’ordre du jour de la semaine, avec une hauteur fixe.
Le calendrier est un module complémentaire : PowerPortalsPro.Web.Blazor.Calendar sur Blazor et @powerportalspro/react-calendar sur React. Ajoutez le package à côté de celui du framework pour l’utiliser.
npm install @powerportalspro/react-calendardotnet add package PowerPortalsPro.Web.Blazor.CalendarNom | Type | Par défaut | Description |
|---|---|---|---|
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 |
AllowFilteringAllowSavedViewsAllowSearchAppointmentDetailsAppointmentsChildContentCssClassCustomViewDefinitionsDefaultLayoutDefaultTablesDefaultViewIdEditableFormLocationHeightIncludeSearchInPersistedStateLayoutsMatchPartiesMultiTableViewIdsPersistedStateQueryParameterRegardingRegardingTablesSaveChangeSavedViewsKeySeriesShowRecordLinksSignInUrlTablesToolbarItemsTooltipTemplateViewIdsViewSortNom | Type | Description |
|---|---|---|
OnAppointmentClick | EventCallback<string> | |
OnRangeSelect | EventCallback<CalendarRangeSelection> |
OnAppointmentClickOnRangeSelectNom | Paramètres | Type | Description |
|---|---|---|---|
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