Skip to content

Commit

Permalink
Merge pull request #54 from rwilson504/IssueFixes
Browse files Browse the repository at this point in the history
Calendar Control Updates
  • Loading branch information
rwilson504 authored May 19, 2020
2 parents 1f2970d + 8a5cd07 commit 35e94c0
Show file tree
Hide file tree
Showing 10 changed files with 289 additions and 215 deletions.
253 changes: 147 additions & 106 deletions Calendar/Calendar/CalendarControl.tsx

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Calendar/Calendar/CalendarControl/Other/Solution.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<LocalizedName description="CalendarControl" languagecode="1033" />
</LocalizedNames>
<Descriptions />
<Version>1.0.148</Version>
<Version>1.0.153</Version>
<!-- Solution Package Type: Unmanaged(0)/Managed(1)/Both(2)-->
<Managed>2</Managed>
<Publisher>
Expand Down
6 changes: 4 additions & 2 deletions Calendar/Calendar/ControlManifest.Input.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<control namespace="RAW.Calendar" constructor="Calendar" version="0.0.151" display-name-key="Calendar" description-key="A Calendar view that can be used in both Model and Canvas apps. Ensure that any fields you define in the parameters are included in your view in a Model App or in your Collection in a Canvas app." control-type="standard">
<control namespace="RAW.Calendar" constructor="Calendar" version="0.0.156" display-name-key="RAW! Calendar" description-key="A Calendar view that can be used in both Model and Canvas apps. Ensure that any fields you define in the parameters are included in your view in a Model App or in your Collection in a Canvas app." control-type="standard">
<data-set name="calendarDataSet" display-name-key="Calendar Data" cds-data-set-options="displayCommandBar:true;displayViewSelector:true;displayQuickFind:false">
</data-set>
<property name="eventFieldName" display-name-key="Event Name Field" description-key="Enter the Event Name Field schema name which will be used to display on the calendar. For related entities use the following format (new_entityname.new_fieldname)" of-type="SingleLine.Text" usage="input" required="true" default-value="name" />
<property name="eventFieldStart" display-name-key="Event Start Field" description-key="Enter the Event Start Field schema name which will be used to display on the calendar. For related entities use the following format (new_entityname.new_fieldname)" of-type="SingleLine.Text" usage="input" required="true" default-value="start" />
<property name="eventFieldEnd" display-name-key="Event End Field" description-key="Enter the Event End Field schema name which will be used to display on the calendar. For related entities use the following format (new_entityname.new_fieldname)" of-type="SingleLine.Text" usage="input" required="true" default-value="end" />
<property name="eventColor" display-name-key="Event Color Field" description-key="Enter the Event Color Field schema name which will be used to display on the calendar. For related entities use the following format (new_entityname.new_fieldname)" of-type="SingleLine.Text" usage="input" required="false" />
<property name="eventDefaultColor" display-name-key="Default Event Color" description-key="Specify the default background color for events if not using a field to define the color. Value should be in Hex color format, eg. #3174ad" of-type="SingleLine.Text" usage="input" required="false" default-value="#3174ad" />
<property name="eventId" display-name-key="Event Id Field" description-key="For Model Apps this is not required but if you are using Canvas you will need to put in the Id field for the Events if you wish to use them." of-type="SingleLine.Text" usage="input" required="false" />
<property name="resourceField" display-name-key="Resource Field" description-key="For a Model App put in the Lookup field of the Resource, for a Canvas app put in the field name that holds the Id of the resource." of-type="SingleLine.Text" usage="input" required="false" />
<property name="resourceName" display-name-key="Resource Name" description-key="For a Model App this is not required but for Canvas apps if you are using resources enter the field name containing the Resources name." of-type="SingleLine.Text" usage="input" required="false" />
<property name="resourceGetAllInModel" display-name-key="Get All Resources" description-key="For Model apps only. If you select true and are using resources then this will ensure that all resources get returned, even those without events in the dataset" of-type="SingleLine.Text" usage="input" required="false" default-value="false" />
<property name="calendarDefaultView" display-name-key="Default Claendar View" description-key="Choose the default calendar view that will be shown. Options are month, week, work_week, day, agenda." usage="input" of-type="SingleLine.Text" required="false" default-value="month" />
<property name="calendarTodayBackgroundColor" display-name-key="Background Color for Today" description-key="Specify the default background color for the calendar space displaying Today. Value should be in Hex color format, eg. #eaf6ff" of-type="SingleLine.Text" usage="input" required="false" default-value="#eaf6ff" />
<property name="calendarView" display-name-key="Claendar View" description-key="Allows you to choose the view that will be shown. Options are month, week, work_week, day, agenda." usage="input" of-type="SingleLine.Text" required="false" default-value="month" />
<property name="calendarDate" display-name-key="Calendar Date" description-key="Allows you to change the calendar date from a Date Field in Canvas Apps" usage="input" of-type="DateAndTime.DateOnly" required="false" />
<property name="calendarLanguage" display-name-key="Calendar Language" description-key="Sets the language/culture of the calendar. In Canvas apps set this to the Language() function. In Model apps you can leave this blank and it will utilize the language set for the current users. Currently support lanuages are en, fr, de, es." usage="input" of-type="SingleLine.Text" required="false" />
<property name="calendarScrollToTime" display-name-key="Calendar Scroll To Time" description-key="Enter the hour of the day (0 - 23) you would like the calendar to automatically scroll to for the day view." usage="input" of-type="Whole.None" required="false" />
Expand Down
24 changes: 21 additions & 3 deletions Calendar/Calendar/css/react-big-calendar.css
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ button.rbc-input::-moz-focus-inner {
background-color: rgba(0, 0, 0, 0.1); }

.rbc-show-more {
background-color: rgba(255, 255, 255, 0.3);
/* background-color: rgba(255, 255, 255, 0.3); */
z-index: 4;
font-weight: bold;
font-size: 85%;
Expand Down Expand Up @@ -309,6 +309,9 @@ button.rbc-input::-moz-focus-inner {
border: 1px solid #DDD;
border-spacing: 0;
border-collapse: collapse; }
.rbc-agenda-view table.rbc-agenda-table tbody > tr{
background-color: transparent !important;
}
.rbc-agenda-view table.rbc-agenda-table tbody > tr > td {
padding: 5px 10px;
vertical-align: top; }
Expand Down Expand Up @@ -356,10 +359,14 @@ button.rbc-input::-moz-focus-inner {
width: 160px !important;
max-width: 160px !important;
min-width: 160px !important;
color: #666;
}

.rbc-agenda-event-cell {
width: 100%; }
width: 100%;
padding: 0 !important;
height: 1px;
}

.rbc-time-column {
display: flex;
Expand Down Expand Up @@ -423,11 +430,22 @@ button.rbc-input::-moz-focus-inner {
max-width: 70px !important;
}

.rbc-time-header-gutter .rbc-time-header-gutter-all-day {
bottom: 0;
position: absolute;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: inherit;
display: inline-block;
}


.rbc-time-view-resources .rbc-time-gutter,
.rbc-time-view-resources .rbc-time-header-gutter {
position: sticky;
left: 0;
background-color: white;
/* background-color: white; */
border-right: 1px solid #DDD;
z-index: 10;
margin-right: -1px;
Expand Down
33 changes: 7 additions & 26 deletions Calendar/Calendar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export class Calendar implements ComponentFramework.StandardControl<IInputs, IOu
private _container: HTMLDivElement;
private _context: ComponentFramework.Context<IInputs>;
private _props: IProps;
private _dataSetVersion: number;
private _selectedRecordId: string;
private _actionRecordSelected: boolean;
private _selectedSlotStart: Date | undefined;
Expand Down Expand Up @@ -51,23 +50,19 @@ export class Calendar implements ComponentFramework.StandardControl<IInputs, IOu
// If any of them are undefined then the onChange event for the control in a canvas app will not fire.
this._currentRangeStart = new Date();
this._currentRangeEnd = new Date();
this._currentCalendarView = context.parameters.calendarDefaultView.raw || "month";
this._currentCalendarView = context.parameters.calendarView.raw || "month";
this._selectedSlotResourceId = '';
this._selectedRecordId = '';
this._actionRecordSelected = false;
this._actionSlotSelected = false;
this._dataSetVersion = 0;

this._updateFromOutput = false;

this._props = {
pcfContext: this._context,
dataSetVersion: this._dataSetVersion,
onClickSelectedRecord: this.onClickSelectedRecord.bind(this),
onClickSlot: this.onClickSelectedSlot.bind(this),
onRangeChange: this.onRangeChange.bind(this),
onDateChange: this.onDateChange.bind(this),
onViewChange: this.onViewChange.bind(this)
onCalendarChange: this.onDateChange.bind(this),
}

this._container.style.height = this._context.mode.allocatedHeight !== -1 ? `${(this._context.mode.allocatedHeight - 25).toString()}px` : "100%";
Expand All @@ -93,11 +88,9 @@ export class Calendar implements ComponentFramework.StandardControl<IInputs, IOu
}

var dataSet = context.parameters.calendarDataSet

//useEffect on the dataSet itself was not picking up on all the updates so pass in a dataset version
// and update it in the props so the react control knows it was updated.
this._props.dataSetVersion = this._dataSetVersion++;

if (dataSet.loading) return;

//CANVAS ONLY
if (context.mode.allocatedHeight !== -1) {
//if we are in a canvas app we need to resize the map to make sure it fits inside the allocatedHeight
Expand All @@ -109,9 +102,7 @@ export class Calendar implements ComponentFramework.StandardControl<IInputs, IOu
// will come back and do a reset on the paging. I beleive this is all due to a MS bug.
dataSet.paging.setPageSize(dataSet.paging.totalResultCount);
dataSet.paging.reset();
}

if (dataSet.loading) return;
}

//MODEL ONLY
if (context.mode.allocatedHeight === -1 && dataSet.paging.hasNextPage) {
Expand All @@ -120,7 +111,7 @@ export class Calendar implements ComponentFramework.StandardControl<IInputs, IOu
dataSet.paging.loadNextPage();
return;
}

this._props.pcfContext = context;
console.log(`updateView: dataSet.sortedRecordIds.length: ${context.parameters.calendarDataSet.sortedRecordIds.length}`)

Expand All @@ -132,12 +123,6 @@ export class Calendar implements ComponentFramework.StandardControl<IInputs, IOu
);
}

public onRangeChange(start: Date, end: Date){
this._currentRangeStart = start;
this._currentRangeEnd = end;
this._notifyOutputChanged();
}

public onClickSelectedRecord(recordId: string)
{
this._selectedRecordId = recordId;
Expand All @@ -154,15 +139,11 @@ export class Calendar implements ComponentFramework.StandardControl<IInputs, IOu
this._notifyOutputChanged();
}

public onDateChange(date: Date, rangeStart: Date, rangeEnd: Date)
public onDateChange(date: Date, rangeStart: Date, rangeEnd: Date, view: string)
{
this._currentCalendarDate = date;
this._currentRangeStart = rangeStart;
this._currentRangeEnd = rangeEnd;
this._notifyOutputChanged();
}

public onViewChange(view: string){
this._currentCalendarView = view;
this._notifyOutputChanged();
}
Expand Down
10 changes: 6 additions & 4 deletions Calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This control has been designed to work in both Canvas and Model apps. Because o
![Control Overview](./images/calendarcontrol.gif)

Canvas
- To ensure data loads correctly in Canvas we must use collections instead of CDS datasources.
- To ensure data loads correctly in Canvas we must use collections instead of CDS datasource directly.
- There are output parameters that are defined in the app which will pass back data when an item is clicked on, an empty time span is selected, or the calendar range has been updated. These output parameters will allow you to create your own functionality in the Canvas app for updated or creating records.
- To set the default lanague for the calendar you can utilize the Lanague() function to pass the users current browser language into the calendarLanguage property.

Expand Down Expand Up @@ -45,10 +45,12 @@ Set the propertie of the control.
- **Event Start Field** This will be the start time for the events. Enter the logical name of the attribute in this fields. Ex. raw_start
- **Event End Field** This will be the end time for the events. Enter the logical name of the attribute in this fields. Ex. raw_end
- **Event Color Field** This will change the color of the event. You can use a color field on the event or you can utlize a color field from the resources. Enter the logical name of the attribute. Ex. on Event raw_color, Ex. on Resource raw_resource.raw_color.
- **Default Event Background Color** Specify the default background color for events if not using a field to define the color. Value should be in Hex color format, eg. #3174ad
- **Event Id Field** (Do Not Use In Model, for Canvas Only were data is supplied by a collection)
- **Resource Field** If you want to utilize resources enter the logical name of the lookup field for the Resource.
- **Resource Name** To use a name field for the resource that is not the default name field you can enter it here. Ex. raw_resource.raw_specialname. Otherwise you can leave this blank and it will use data from the default name field.
- **Get All Resources** Determines if all resources will be returned even those that don't have any events on the calendar. Possible values are true or false.
- **Today Background Color** Sets the background color for the time slots that cover todays date.
- **Default Claendar View** Set the default calendar view. Possible values are "month", "week", "work_week", "day", "agenda"
- **Calendar Date** (Do Not Use In Model, for Canvas Only)
- **Calendar Language** Allows you to set the default language/culture for the calendar. If you leave this blank it will default to the users current language in Dynamics if it's available or you can specifiy a lanuage if you always want the calendar to show up in that language.
Expand All @@ -61,12 +63,12 @@ Using the control in Canvas requires more configuration due to the limitations a
- Using Code Components in a canvas app is currently in pre-release. You will need to follow [these directions](https://docs.microsoft.com/en-us/powerapps/developer/component-framework/component-framework-for-canvas-apps) in order to enable this feature within your environment.
- After you drop the calendar control onto your Canvas app or update any of the controls properties make sure that you close and re-open the app in the PowerApps Editor to see the changes reflected.
- When adding the control to the form it will have a long name like raw_RAW.Calendar.Calendar(00000001-0000-0000-0001-00000000009b1) rename it to something simple like Calendar Control
- Because Canvas apps utilize delegation our datasource for the control will need to be a Collection as apposed to using the CDS entity directly, directions on how to do this are below.
- Because PCF Code components are not currently in Preview from Microsoft there are some paging bugs that limit the number of records return when using a CDS entity directly, instead you will need to utilize a Collection to get the data. directions on how to do this are below.

## Events Only
To just get the events and display them on the calendar we must utilize a simple collection to get all the events. Because Canvas apps utilize delegation we need to load all CDS data into a collection, otherwise the number of records will be constrained.
To just get the events and display them on the calendar we must utilize a simple collection to get all the events. Because Canvas have some paging issues right now we will need to load the CDS data into a collection, otherwise the number of records will be constrained to 25.

The following code can be added to the OnVisible event of the Canvas form. The collection name will be calendarEvents and the CDS entity we are pulling from is called Events. Additionally you can add filters when creating the Events entity if you would like to only show certain events.
The following code can be added to the OnVisible event of the Canvas form or to a Toggle switch that can update the data when it's been checked.. The collection name will be calendarEvents and the CDS entity we are pulling from is called Events. Additionally you can add filters when creating the Events entity if you would like to only show certain events.

![OnLoad of Screen](./images/CanvasCalendarEventsOnlyOnLoad.png)

Expand Down
11 changes: 6 additions & 5 deletions DetailListGrid/DetailListGrid/DetailListGridControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import * as lcid from 'lcid';

export interface IProps {
pcfContext: ComponentFramework.Context<IInputs>,
isModelApp: boolean
isModelApp: boolean,
dataSetVersion: number
}

interface IColumnWidth {
Expand Down Expand Up @@ -50,14 +51,14 @@ export const DetailListGridControl: React.FC<IProps> = (props) => {
// When the component is updated this will determine if the sampleDataSet has changed.
// If it has we will go get the udpated items.
React.useEffect(() => {
console.log('sampleDataSet was updated');
console.log('TSX: props.dataSetVersion was updated');
setItems(getItems(columns, props.pcfContext));
}, [props.pcfContext.parameters.sampleDataSet]);
}, [props.dataSetVersion]);

// When the component is updated this will determine if the width of the control has changed.
// If so the column widths will be adjusted.
React.useEffect(() => {
console.log('width was updated');
//console.log('width was updated');
setColumns(updateColumnWidths(columns, props.pcfContext));
}, [props.pcfContext.mode.allocatedWidth]);

Expand Down Expand Up @@ -244,7 +245,7 @@ const getColumnWidthDistribution = (pcfContext: ComponentFramework.Context<IInpu

// Considering need to remove border & padding length
let totalWidth:number = pcfContext.mode.allocatedWidth - 250;
console.log(`new total width: ${totalWidth}`);
//console.log(`new total width: ${totalWidth}`);
let widthSum = 0;

columnsOnView.forEach(function (columnItem) {
Expand Down
Loading

0 comments on commit 35e94c0

Please sign in to comment.