If you have ever used Office Fabric with SPFx, you may have found yourselves struggling.  You quickly learned than previous version of SPFx did not work with version 6+ of Office.  Instead you had to use the LTS version of Office Fabric which varies significantly from version 6.  What make this such a pain point is that there isn't really any documentation on the Office Fabric site that tells you that.  Instead you just installed it, tried it out, and couldn't figure out why things weren't working until you did an Internet search.  In addition what made things even harder is that many of the parameter and function names have changed between version 5 and 6.  The documentation only covers what's in version 6.  Some functionality flat-out isn't there in version 5 and you had to find work-arounds.  This pain ends today with SPFx 1.8.

First, install the latest version of SharePoint Framework 1.8 by running the following:

npm install -g @microsoft/generator-sharepoint

Once it completes, start a new project or follow the instructions in the release notes on how to migrate your existing project.  Start a new branch if you are migrating an existing project.

Now install Office Fabric with the following command:

npm install office-ui-frabric-react

Now, add your favorite Office Fabric React code for buttons, pickers, command bars, etc.  Finally run gulp serve.  Unfortunately, you'll still see the errors in merge-styles that we have always gotten when trying to use v6 of Fabric React.  That's because Fabric React needs a newer version of TypeScript.  SPFx 1.8 now supports TypeScript 2.7.2 by default.  That's not good enough. Luckily, we can use other versions of TypeScript now.  I tried to use 3.3 but couldn't get it to work.  However, I could get it to work by using 3.0.  Here's how you do that.

In your package.json file, replace the @microsoft/rush-stack-compiler-2.7 dependency with 3.0 as follows:

"@microsoft/rush-stack-compiler-3.0": "0.5.9"

Now, update your tslint.config and change the extends line to the following:

"extends": "./node_modules/@microsoft/rush-stack-compiler-3.0/includes/tsconfig-web.json",

Now run the following command:

npm install

Your Fabric React 6 components should now be working when you run your project again.  Here's my example with a command bar and a button:

Screen Shot 2019-03-14 at 4.04.08 PM

If you want to look at my code changes, you can see them in this simple repo.

These are exciting times and this should make working with Office Fabric React much easier.

On any consumer-facing platform where users can submit content that will be seen by the public, it's a good idea to have some level of content moderation.  Manual content moderation using humans is tedious and labor-intensive.  Luckily, Azure Content Moderator, part of Azure Cognitive Services, provides us with some AI capability to potentially detect language that might be offensive.  It's actually quite easy to get started with as well.

First, you'll want to create a new Content Moderator in your Azure Portal.  The options are fairly straight forward based upon region, resource groups, and scale.  For this example, I used the F0 Plan which comes with 5000 moderation transactions a month (full pricing details).  This should be more than enough to prove out the concept.

Screen Shot 2019-03-04 at 2.35.21 PM

When your Content Moderator finishes provisioning, go to the Keys tab and make note of Key 1 and Key 2 here.  You'll use this later.  Keep these keys secure so that others don't use your API calls.

In this example, we are using Ionic Framework 4.0 which just hit general availability fairly recently.  We'll build on a simple out-of-the-box app.  Full source code is available at the link at the end of this post.  If you don't have Ionic Framework installed, you can install it from here.   To start a new project in Ionic Framework, issue the following command.

ionic start IonicAzureContentModerator

After the project has been created, you can see it in the browser by running the following command:

ionic serve

This will launch the app in a web browser with live reload.  Now let's add the components we need to test this out.  First, let's create a service to make our call to Azure.  Normally this service would call our own API or function which would proxy the call to Azure Content Moderator.  We do this so that our API key is not stored in the client application.  For simplicity though, we are going to call Azure directly because this is only an example.  To create the service issue the following command in the Ionic CLI.

ionic g service services/ContentModeratorService

This will create a stub for a service. We'll look at what goes in here shortly.  However, since we are going to be making an Http call, we need to add the angular HttpClientModule.  Open app.module.ts and add the following import:

import { HttpClientModule, HttpClient } from '@angular/common/http';

Next add HttpClientModule to the list of imports of @NgModule.

Now let's go back to our service and we'll start by adding our HttpClientModule reference.

import { HttpClient, HttpHeaders } from '@angular/common/http';

We also need to add the HttpClient to our constructor to create an instance.  Finally, we have a simple method called moderateContent which calls the Azure Endpoint for the Content Moderator.  The first step is to assemble a URL to that endpoint.  This URL varies by region so you will need to look up what the URL is based on where you deployed your Content Moderator.  The API has a few parameters including whether to scan for PII as well.  As a result, I've made that a parameter on my function.  Here is what my URL looks like for South Central US.

let apiUrl = `https://southcentralus.api.cognitive.microsoft.com/contentmoderator/moderate/v1.0/ProcessText/Screen?PII=${PII}&classify=true`;

Next, we construct an HttpOptions object to pass the API Key.  It goes in a header by the name of Ocp-Apim-Subscription-Key.  I store the API key in the value Constants.apiKey.  Again, we wouldn't normally store our API key in a client application like this.

const httpOptions = {

headers: new HttpHeaders({

'Ocp-Apim-Subscription-Key': Constants.apiKey

})

};

Finally we make the HTTP POST while passing the content that we want to moderate in the body.

Now, we can build a simple form to collect the user's input and make the call to our service.  I add an ion-textarea to collect the user's input and add a toggle to choose whether or not to scan for PII.  Then I just make use of some ion-badge components to display the results.  Here is what our interface looks like in the browser.

Screen Shot 2019-03-04 at 3.19.50 PM

Here is the HTML code.

Screen Shot 2019-03-04 at 3.20.58 PM

Clicking the button simply executes the moderateContent method in the service we created.  Let's look at the data that comes back when we execute a call. 

Screen Shot 2019-03-04 at 3.27.12 PM

In the Content Moderator response, we receive a Classification object and in that object there are three categories returned: Category1, Category2, and Category3 along with a boolean ReviewRecommended which will return true if the text is likely an issue.  The categories are defined as follows:

  • Catagory1 - refers to potential presence of language that may be considered sexually explicit or adult in certain situations.
  • Category2 - refers to potential presence of language that may be considered sexually suggestive or mature in certain situations.
  • Category3 - refers to potential presence of language that may be considered offensive in certain situations.

Each category contains a decimal value between 0 and 1.  The higher it is, the more likely the content applies to that category.  In this case, the phrase we sent is more of a general profanity as opposed to being sexual of nature. 

In our app, we simply bind these values using the ion-note so that you can easily see how the phrase was interpreted.

Screen Shot 2019-03-04 at 3.35.05 PM

If you use the toggle for PII, you can look for things such as national id numbers, phone numbers, addresses, and IP addresses.  Here is an example of the output.  You can find more information in the docs.

Screen Shot 2019-03-04 at 3.37.20 PM

You can observe the values of potential PII using the PII object.  You'll notice in this case as well that the Classification values were significantly lower because there wasn't any offensive text in the string we sent.

Azure Content Moderator part of Cognitive Services is a great way to test content to see if it's potentially offensive.  While you will still want to incorporate a human review element into any content moderation process. This should help automate some of the process for you.  In addition, Cognitive Services has Content Moderation for images which can identify potentially suggestive images.

If you want to dive deeper, you can take a look at my code sample in GitHub.



with no comments
Filed under: , ,

The yo tools make it rather easy now to add additional web parts and extensions to your SPFx projects.  However, I recently ran across this issue which caused me weeks of pain.  The scenario starts with this. You create a new SPFx project with a web part and deploy it.  Everything works great.  Now, you go and create an application customizer to add your own navigation or footer.  Here is where you start to run into issues.  You can add the application customizer easily enough with yo, but when you increment your version number in package-solution.json and then deploy it, you will find your web part to be missing.  Your application customizer will work fine though.

All of this trouble comes from package-solution.json.  When you initially create an SPFx project with a web part, no features included in package-solution.json and the web part deployment just works.  However, when you add the application customizer, it creates a feature to deploy the application customizer.  Since there is no reference to the existing web part which means it no longer gets deployed.

{
   "$schema": "
https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
   "solution": {
     "name": "web-part-plus-app-customizer-client-side-solution",
     "id": "64380dc5-ce1e-4227-9b47-5ca7f9134d12",
     "version": "1.0.0.1",
     "includeClientSideAssets": true,
     "isDomainIsolated": false,
     "features": [
       {
         "title": "Application Extension - Deployment of custom action.",
         "description": "Deploys a custom action with ClientSideComponentId association",
         "id": "82cb0cda-24bf-4aec-87df-c9571f82ad6b",
         "version": "1.0.0.1",
         "assets": {
           "elementManifests": [
             "elements.xml",
             "clientsideinstance.xml"
           ]
         }
       }
     ]
   },
   "paths": {
     "zippedPackage": "solution/web-part-plus-app-customizer.sppkg"
   }
}

Your first inclination might be to add a feature for the web part.  Don't do that!  It will cause numerous issues for you in which SharePoint will load old versions of your code intermittently (see issue #3199).  Instead, you need to add a component id for each web part AND your application customizer into a single feature.  To be clear, you can only have a single feature in an SPFx project.  This is at least in the context of web parts and extensions.  I don't know how this would affect a feature that deploys declarative components such as site columns or content types. 

Here is what a package-solution.json looks like that will properly deploy a web part and an application customizer. 

{
   "$schema": "
https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
   "solution": {
     "name": "web-part-plus-app-customizer-client-side-solution",
     "id": "64380dc5-ce1e-4227-9b47-5ca7f9134d12",
     "version": "1.0.0.2",
     "includeClientSideAssets": true,
     "isDomainIsolated": false,
     "features": [
       {
         "title": "Application Extension - Deployment of custom action.",
         "description": "Deploys a custom action with ClientSideComponentId association",
         "id": "82cb0cda-24bf-4aec-87df-c9571f82ad6b",
         "version": "1.0.0.2",
         "assets": {
           "elementManifests": [
             "elements.xml",
             "clientsideinstance.xml"
           ]
         },
         "componentIds": [
           "2c3bc847-128a-4ed9-94b2-3f46b02e6924",
           "5bd48a40-6b4a-45b5-a919-95d12c9137a0"
         ]
       }
     ]
   },
   "paths": {
     "zippedPackage": "solution/web-part-plus-app-customizer.sppkg"
   }
}

Under componentIds you will see two ids.  The first is the id for the Application Customizer.  This isn't the feature id, it's the id in the manifest file for the application customizer.  The second component id is the id of the id of the web part (you also get that from the manifest).

When I was looking to originally add an application customizer to my web part project, I didn't find a lot of guidance on it.  You can reference my GitHub project with the issue.  The master branch has the issue, the WebPartWithApplicationCustomizer branch does not have the issue.  I've also logged an issue (#3219) for this scenario in GitHub because I think it could affect others as well.

If you are still connecting to an on-premises Exchange Server in Outlook for Mac OS X, you may receive the following error even though your password is correct:

Mail could not be received at this time.

The server for account "" returned the error "Login failure: unknown user name or bad password."  Your username/password or security settings may be incorrect.  Would you like to try re-entering your password?

Screen Shot 2018-12-06 at 10.25.44 AM

Outlook will continue to prompt you several times as it attempts to download your messages.  The problem is that it usually will never stop even if you click the option Remember the password in my keychain.  In this state, you can usually get it to give you your mail if you enter your password enough times, but it won't stay connected and you won't be notified when you get new e-mail.

Screen Shot 2018-12-06 at 10.25.55 AM

This has issue has been occurring for me since at least August on both of my Macs and finally I got frustrated enough to try and resolve it.  I searched in the Internet and found a few references to the error but no solution.  I started by reaching out to my client's IT support and seeing if they ever saw the issue but surprisingly they never had.  Maybe it's only an issue with the Office Insider Fast Ring.

Then, I used the Contact Support option in the Help menu of Outlook.  I provided my log information and described the issue.  I had a response in under 5 minutes.  It turns out this is a known issue and there is no estimate for a fix on it.  Here is a snippet of the response I received.

Please accept our apologies. This issue has been reported and we are aware and investigating. I also added your ticket to the report to get it fixed the soonest possible! We are sorry, we have no information on when a fix will be rolled out. We appreciate your understanding and patience. 

The good news is that this is a known issue.  The bad news is they don't have any idea on resolution yet.  Unfortunately, this is an issue affecting an on-premises environment which means its priority for resolutions is probably quite low.  Keep your fingers crosses if you are chasing this issue.

with no comments
Filed under: , , ,

Recently, I posted about the error (TypeError: Object doesn't support property or method 'from') you received in Internet Explorer 11 (IE11) when you didn't include the necessary polyfills for PnP JS to work.  To resolve the error, previously you had to include the following Polyfills to provide support for things like proxy, fetch, and map.

import "core-js/modules/es6.promise"

import "core-js/modules/es6.array.iterator.js"

import "core-js/modules/es6.array.from.js"

import "whatwg-fetch"

import "es6-map/implement"

Now with PnPJS 1.2.4, this has been simplified a bit with a new single package.  First, install the package @pnp/polyfill-ie11.

npm install --save @pnp/polyfill-ie11

Now remove all of the previous imports from your web part class and replace it with the following single import.

import "@pnp/polyfill-ie11";

Now, give your code a try inside Internet Explorer.  All of your PnPJS calls should work normally.  What's nice about this version of the Polyfill si that we have support for SearchQueryBuilder which I believe wasn't there before.

You can read more about the new Polyfill package on the PnPJS site.

Apple recently gave developers the ability to sign up testers using just a URL in TestFlight.  Previously, it required the developer to manage a list of E-mail addresses which quickly becomes unwieldy.  If you are interested in testing pre-release versions of Word, Excel, Outlook, and more then check out the links below.  You first need to install the TestFlight app on your iOS device.  This is how you install pre-release apps in iOS.  In fact, all of the links you see today need to be accessed directly from your iPhone or iPad.  Click on any of the links below to get started.

As usual, if you install pre-release software, you assume all risk such as the app not working, crashing, or worse.  Another thing to remember is that TestFlight only allows 10,000 users in a beta test.  Therefore,you may not be able to join the test at some point when either they run out of invitations or MIcrosoft closes the program early.

with no comments
Filed under: , ,

We were discussing build times in #ionic-questions Slack channel today and Mike noted that you should be on Node v10.  Apparently, the @LTS has some bugs that are affecting performance.  If you haven't upgraded and plan to do any work with Ionic v4.0, I recommend it.  It significantly improves build and refresh tine.  Specifically, I installed v10.12.0. 

with no comments
Filed under:

The  Fabric React DetailsList component is a great way to display your tabular data when building an SPFx web part.  It's nice, but if you have a lot of rows in your list, you might need a sticky header so that you can see which column you are looking at.  As a developer building out this scenario for the first time, you might run into guidance and a code sample from the ScrollablePane documentation.  I found this hard to find because I would expect this example to be linked to the DetailsList documentation.  This will get you up and going fairly quickly.  However, when you are implementing it using the code sample, you'll find that there isn't an event called onScroll on DetailsList when you are building an SPFx web part.  That's because that event doesn't exist in Fabric React 5.  Maybe you proceed anyways and notice that the sticky header is working just fine. At least you thogught it was working.

Here's where the problem starts.  if you have a lot of columns (or your users' screen resolution is very low), you may need to deal with horizontal scrolling.  Nothing good ever comes from horizontal scrolling.  When you need to horizontally scroll, a scrollbar appears in the sticky header.  Great.  That's exactly what you wanted.  The problem is the rows in the grid, don't scroll with it.  Now you have columns that don't line up to the data.  That's a problem. 

When trying to fix it, you might run into the following issue on GitHub.  This pointed me in the right direction.  The answer is to react to the scroll events and set the scrollLeft property to match.  You need to create a new function to listen to the scrolling of the div element.  This effectively responds to the scrolling of the div element where your content is and sets the scroll of the Sticky to match it.  It's pretty simple.

private handleScroll(event) {
let element = document.querySelector("[class*='stickyAbove-']");
if (element != null)
element.scrollLeft = event.target.scrollLeft;
}

Then all you need to do is add the event to your div element that contains the ScrollablePane.

<div
   style={{
     height: '1000px',
     position: 'relative',
     maxHeight: 'inherit'
     }}
    onScroll={this.handleScroll}
>

This helped me to part of the solution but not all of it.  This only handles when the user scrolls the data using the scrollbar at the bottom.  What we need to add to it is an event to respond to when the user scrolls the Sticky element.  I did this by registering an event handler in componentDidMount.  I used pure JavaScript in my example, but you could reference the Sticky component using componentRef if you wanted.

public componentDidMount(): void {
let stickyElemrent = document.querySelector("[class*='stickyAbove-']")
if (stickyElemrent != null) {
stickyElemrent.addEventListener('scroll', this.hnadleStickyScroll);
}
}

In my event handler, we have similar code except that we are getting a reference to the DetailsList element.

 private hnadleStickyScroll(event) {
let gridElement = document.querySelector("[class*='ms-DetailsList']");
if (gridElement)
gridElement.scrollLeft = event.target.scrollLeft;
}

Once you add this, you should be able to scroll your rows of content or the sticky header horizontally and they will stay in sync.  If you have run into this issue, give it a try.

with no comments
Filed under: , ,

You just built this amazing SPFx web part and it works great in modern browsers.  You then go to test (or even worse your users go to test) and you find that nothing works.  After examining your logs, you start finding the following error message.

TypeError: Object doesn't support property or method 'from'

What does that mean?  Basically, all of your calls to SharePoint made through PnPJS are failing.  You start to panic as you realize everything you built doesn't work in IE11.  Not to worry though, this can be fixed.  After doing some research, you might stumble upon this issue reported in GitHub.  The reason for this is that in version PnPJS 1.2.0, they dropped direct support for Internet Explorer.  That doesn't mean you are out of luck though and you need to go tell the client the solution you spent weeks on won't work for half their users.  You just need to add the right polyfills to your project and you are back in business.

Just add the following polyfills to the relevant part of your project.

import "core-js/modules/es6.promise"

import "core-js/modules/es6.array.iterator.js"

import "core-js/modules/es6.array.from.js"

import "whatwg-fetch"

import "es6-map/implement"

I find that if you are developing an SPFx web part, you can just add this to the web part's class (not the React component).  Add them anywhere near the top of that class and your IE users should be able to use your web part as intended.

Today, Microsoft released the long waited Files-On-Demand support in macOS Mojave. As you might know Files-On-Demand (or FOD) has been available in Windows 10 for a while but it has been a featured that we have been waiting for in macOS for quite some time. Now at Ignite, Microsoft is giving you the opportunity to try it out. In order to try it out, you first have to upgrade to macOS Mojave 10.14. The latest version of macOS just came out today on September 24th and is now available to download. If you are running on a beta version still, you can try it out as well.

The second thing, you need to do is make sure you are in the Insiders Ring for Office and / or OneDrive. If you aren’t sure, download the script from the installation site. It’s a bash script, so you will need to make the script executable. If you aren’t familiar with this process, you have to get back to the Unix / BSD roots of OS X. Open a new Terminal, and go to the directory where you downloaded the script and then execute the following command:

chmod u+x ./EnableMacFilesOnDemand.sh

Screen Shot 2018-09-24 at 1.32.24 PM

If you’ve had OneDrive installed on your Mac before, you’ll need to delete some cache files in the following folder: ~/Library/Caches/OneDrive. Delete *.json in that folder.  I didn't actually do this step, but you may need to.

Now you can install the OneDrive client. Download the client from the install link and then go through the install process. Launch OneDrive when it’s complete. If you run into issues, there are a few troubleshooting tips about force closing Finder. I didn’t have to do that but you may need to on your machine.

If you have enabled the new macOS Mojave Dark Mode, the first thing you might notice is that the OneDrive client respects that and will also show using Dark Mode. Good job, OneDrive engineering team! That makes for a nice experience.

Screen Shot 2018-09-24 at 1.40.33 PM

I had to setup one of my Office 365 accounts on this particular machine but that’s good because it gave me an idea for the new account setup experience. After you sign in, you’ll get this new dialog that explains the icons that you will see in Finder.  Cloud = online only, checkbox = the file is on disk.  This is helpful, because I’ve always had trouble remembering what the icons mean in FOD for Windows 10.

Screen Shot 2018-09-24 at 1.11.55 PM

For existing accounts, you may need to turn on Files-On-Demand manually. I didn’t have to in my case, but it’s good to know where to go. Go to Preferences in OneDrive and then look for the Files-On-Demand section. You can see verify whether it has been turned on or not.

Screen Shot 2018-09-24 at 2.27.40 PM

Now we can go find our OneDrive folder inside Finder and see how it all works. When I open one of my synced folders, you’ll notice that I am now seeing files that I have not downloaded yet indicated by the cloud icon next to each one. That’s right, I am seeing files that are online, but not yet downloaded.

Screen Shot 2018-09-24 at 1.45.20 PM

Clicking on an online file will immediately download it and you can access it like you had it all along. This is what we have been waiting for. If you right click on a file, you now see the option to Always keep on this device. This is how you tell OneDrive to keep that file on your device for offline use.

 Screen Shot 2018-09-24 at 1.43.28 PM

Once you do that, you’ll notice the icon changes from a cloud to a check mark.

Screen Shot 2018-09-24 at 1.44.10 PM

I’m looking forward to using this on a day-to-day basis. This should make working with OneDrive files online and offline much easier with macOS Mojave 10.14.

with no comments
Filed under: , ,

With React, sometimes the simplest of things are overly complicated.  When it comes to creating a page anchor so your users can jump down to a specific point in the page, this one is no exception.  From our old HTML4 days, you probably remember you create an anchor by doing something like the following:

 <a name="my-anchor-name"></a>

When you look for the name attribute of an anchor in React though, it's nowhere to be found.  Ultimately this has to do with React's routing system, but that doesn't really do you any good in your SPFx Web Part.  How do you get around it?  One way is to use the Link component from Fabric React.  You'll notice it does have a name attribute but using it isn't quite straight forward.  First, include Link on the page you are building.

import { Link } from 'office-ui-fabric-react/lib/Link';

Once you do that, add your Link to the page using the name attribute and a unique identifier.  This will be the destination we are jumping to.

<Link name={'my-uniqud-id'} href={'#'}></Link>

You might be wondering why I have the href tag there on the anchor tag.  That is because the Link element renders a Link element as a button instead of an anchor tag if there isn't an href tag.  You can include any value you want there, but a value is required.

Now to jump to our anchor tag, use the Link tag and include a hash tag and your unique identifier.

<Link href={'#my-unique-id'}></Link>

Again this seems like a simple topic, but if you are new to React because you just started SPFx development, this might take you a minute to figure out.

Contrary to popular belief, I still do development.  In fact, I do quite a bit of development.  In the last couple of years, I have built two mobile platforms as a service using Ionic and Angular.  This node.js based development stack positioned me well to start working with SPFx.  I'm starting up a string of blog posts that help cover the basics that I think that we often overlook in the bigger picture of how to do things with SPFx.  Today's topic is simple: reading a value from the query string.  When I recently looked at this simple scenario, I thought sure I could go back to my JavaScript roots and use location.href but there has to be a better way now right?  The SPFx team thought of that and they included a nice helper class to get you going called UrlQueryParameterCollection.

Start by including a reference to UrlQueryParameterCollection.

import { UrlQueryParameterCollection } from '@microsoft/sp-core-library';

We use the getValue() Like ASP.NET or other languages, you'll usually want to check to see if it has a value before using it.  I then cast it to an integer time after reading the value.

if (queryParameters.getValue('id')) {
        id = parseInt(queryParameters.getValue('id'));
}

Again, this is a simple example, but hopefully it will keep you from going down the path with location.href.  The sp-core-library has all sorts of useful utitlities for you to use such as Environment, Random Number Generators, and logging.  Check it out the next time you start out a project.

When you add a date field in PowerApps, I find that the current default date of 12/31/2001 is not very useful for me.

PowerAppsDefaultDate

Changing the default date is not hard but you have to know where to look.  First, you have to realize a date field is actually three different controls DateValue, HourValue, and MinuteValue.  The default has to be set on each one. 

Start by clicking on the Date Value where is says 12/31/2001.  In the properties, go to the Advanced Tab and click the Unlock button. Now, iIn the property selector, look for DefaultDate and change the value to Now().

PowerAppsDefaultDateSelected

You'll notice the date changes to today's date now.  You can also use date manipulation functions if you want to choose another date.  Now, if you don't like the time defaulting to midnight, we can change that too.  Click on the HourValue and choose Default in the property selector.  Notice the formula it has.

PowerAppsDefaultDateHourBeforeChange

Let's change that to use today's date and time to get the default value with the following formula.

Text(Hour(Now()), "00")

You'll notice the hour has now updated.  PowerApps may apply a region identifier to your string when you update it.  That won't mess anything up.

PowerAppsDefaultDateHourBeforeChange

Now repeat the process for the MinuteValue with the following formula

Text(Minute(Now()), "00")

PowerAppsDefaultDateMinuteValueChanged

That's all there is to it.  It may take a few extra steps than you expected but the process is pretty easy to follow.

with no comments
Filed under: ,

The new Microsoft Teams & Skype for Business Admin Center is starting to roll out to first release.  This post will show you some of the highlights and how to get started.  First, you have to know where to find it.  Currently, the Microsoft Teams & Skype for Business Admin Center does not show up in the list of Admin Centers on your Tenant.  To find it in your Admin Center, go to Settings -> Services & add-ins and then Microsoft Teams

TeamsAdminCenterSettingsLink

If the new admin center has been provisioned on your tenant, you will see a message at the top warning you that some settings are only available in the new admin center.

TeamsAdminSettingsMigrated

Click on the link to take you to the new admin center.  It will take you to the URL below.

https://admin.teams.microsoft.com/

The will take you a dashboard that looks a bit incomplete for the moment.  It lets you quickly get to your users as well as some help videos.

TeamsAdminCenterDashboard

On the Users page, you can see a dashboard of users, phone numbers (if any) and that one policy has been defined.  It looks like the RestrictedAnonymousAccess policy is assigned to everyone by default.

TeamsAdminCenterUsers

When you click on a user, you see a screen with some general information including the conference bridge and phone number (if assigned).  Here you can reset the conference ID or PIIN, set policies, and set defaults.

TeamsAdminCenterUser

If you click Edit next to Assigned policies, it will let you change the Teams Messaging policy but you cannot change the Teams Meeting Policy yet.  The option simply isn't present when you click on it.  I suspect that will come later in the future.

TeamsAdminCenterUserPolicy

If you click Edit next to Microsoft Teams, you can set the Default calling app and the Default chat appEach one has a value of Teams, Skype for Business, or Default.  However, when you try to change the Default calling app, you get an error:

This combination of preferred applications isn't allowed.

TeamsAdminCenterUserDefaults

I suspect this will be resolved in the future as more of the Interop features on the roadmap are launched.

Under Meetings, you can now manage your conference bridge phone numbers.  This is a welcome change from the old Skype for Business audio conference settings.

TeamsAdminCenterMeetings

Clicking Settings takes you to bridge settings include entry and exit notifications and PIN length.

TeamsAdminCenterMeetingsSettings

In reality, not that many settings have been migrated to the new admin center yet.  The most noticeable move will be the Messaging settings.

TeamsAdminMessagingMoved

Here you will see the new expanded Teams messaging policy with the ability to set more than one policy now.

TeamsAdminCenterMessagingPolicies

You can control External Access under Org-wide settings.  This is where you can turn off communication to external Skype (consumer) users.  By the way, Secure Score actually recommends you turn off communication to Skype users now.

TeamsAdminCenterExternalAccess

Under Guest Access you can control all of the settings that you allow guests of your Teams to do.

TeamsAdminCenterGuestAccess

That's all of the new settings for now.  Like the new SharePoint Admin Center, many of the legacy settings will take some time to migrate over to this new experience.  If you can't find the setting you are looking for, go back to the Skype for Business admin center or the Teams Settings menu.

One particular feature in Microsoft Teams that has been a success in my organization is the use of Cloud Storage to provide a hierarchy in Microsoft Teams. If you are not familiar with what I am talking about, I am referring to the Add cloud storage link you see in the Files tab of a Team.  You might have glossed over this link since you may be fully on Office 365, but this particular link has a lot of power.

TeamsAddCloudStorage2

Clicking that button will take you to a screen asking you which cloud storage provider you want to use.  In our case, we want to use SharePoint.

TeamsAddCloudStorageChooseProvider

However, you may have different options.  That's because they can be configured in the Office 365 Admin center under Settings -> Services & Add-ins -> Microsoft Teams -> Custom cloud storage.

TeamsCustomCloudStorageAdmin

Note, how most of mine are turned off.  Google Drive is about to join the off-club as well for us.  Having just migrated my organization off of G Suite this cloud storage provider approach has acted as a good transition since Google makes use of the virtual folders concept quite a bit.

Now back when the user chooses SharePoint, it will present you a list of sites that it thinks might be relevant to you.  However, you can also paste in a link from any SharePoint site you have.  Don't worry about trimming the link or getting it exact either.  You can paste the URL of the site root, a document library, whatever.  Teams will figure out the site you want.

TeamsAddSharePointLink

Paste your URL,  select the site, and then click Next.  Now pick the document library you want to link in.

TeamsCloudStorageDocumentLibrary

Finally click Add Folder.

You will be returned to the Files tab.  This part is a bit buggy because while the tab does refresh, it doesn't show you your new link.  Just switch off the tab and click back on the Files tab and you will then see your new link.

TeamsWithVirtualLink

It will create a link to the child site with a special SharePoint folder icon.  It names your folder based off of the site name and document library name.  Unfortunately, you don't have any control of that name and you can't rename it.

When you click on the link, it will let you drill down into the document library of that site you linked in.  Notice it even maintains the bread crumbs from the Team you came from.

TeamsChildSiite

This is a great way to bring links to content from all over your organization into one central location.  It's pretty useful I think.

What's the downside?

I think the only other downside is that you can only see these links from the Teams client.  If you go into SharePoint directly, you won't see those links in your document libraries.  It's still pretty useful though.  Give it a try!

More Posts Next page »