Hello, Power Platform Devs! In this blog post, I’d like to highlight my learning experience with the AIS HUB Team that you can take advantage of to get started with Power Platform fundamentals.

What is the HUB Team?

The AIS Cloud Acceleration Hub (HUB) is a dedicated team of AIS consultants organized to help our project teams deliver successful cloud solutions. The HUB team consolidates knowledge and experience to provide rapid research and guidance services for AIS delivery teams at no additional cost to our customers.

What is Power Platform?

Power Platform is a business application platform that allows users to create and deploy applications with the help of its four components.

The four components of Power Platform

Components of Power Platform

Power Apps

Power Apps provides a rapid low code development environment for building custom apps for business needs.

Key features:

  • Low/no-code platform for building apps
  • Work with data where it lives.
  • Add artificial intelligence to your app with no code

Types of Power Apps:

  • Canvas Apps – Canvas apps are a great option when you want to build an app from a blank canvas. You start by choosing the screen size: tablet or mobile
  • Model-Driven Apps – Model-driven app design is a component-focused approach to app development.
  • Portals – Portals bring the power of no-code solutions to building external-facing websites. You can build an anonymous or authenticated website through the Power Apps interface that allows users to interact with data held in Dataverse.

PARTNER OF THE YEAR FINALIST
AIS was recognized as a Finalist for the Microsoft 2021 Power Apps and Power Automate Partner of the Year Award.

Power Automate

Power Automate lets users create automated workflows between applications and services. It helps automate repetitive business processes such as communication, data collections, and decision approvals.

Key features:

  • Automated workflows between applications and services
  • Process Automation
  • Provides Saved Templates

Types of flows:

  • Event-Driven Flows – These are flows that you build with a trigger and then one or more actions. There are many triggers and actions available, thanks to the existing connectors.
  • Business Process Flows – These flows are built to augment the experience when using Model-driven apps and the Dataverse. Use these to create a guided experience in your Model-driven apps.
  • Desktop Flows – These robotic process automation (RPA) flows allow you to record yourself performing actions on your desktop or within a web browser.

Beyond simple workflows, Power Automate can send reminders on past due tasks, move business data between systems on a schedule, talk to more than 275 data sources or any publicly available API.

INTERNAL POWER PLATFORM HACKATHON
AIS held an internal hackathon for Microsoft Power Platform to expose our team to the platform, concepts, approaches through hands-on experience.

Power BI

Power BI (Business Intelligence) is a business analytics service that delivers insights for analyzing data. It can share those insights through data visualizations which make up reports and dashboards to enable fast, informed decisions.

Key features:

  • Business analytics service that delivers insights for analyzing data. It helps with the following:
    • Connect to Data
    • Transform Data
    • Visualize Data

Building Blocks of Power BI:

  • Datasets
  • Reports
  • Dashboards

Power BI lets you easily connect to your data sources, clean, and model your data without affecting the underlying source, visualize (or discover) what’s important, and share that with anyone or everyone you want.

Power Virtual Agents

Power Virtual Agents enables anyone to create powerful chatbots using a guided, no-code graphical interface without the need for data scientists or developers.

Key features:

  • Create chatbots using a guided, no-code graphical interface

Minimizes the IT effort required to deploy and maintain a custom solution. We can perform the following tasks:

  • Create a chatbot
  • Test a chatbot
  • Publish a chatbot
  • Analyze a chatbot

Hands-on Links:

Conclusion

Power Platform features offer several features. Some of my favorites on Power Platform are AI Builder, which allows users and developers to add AI capabilities to the workflows. Microsoft Dataverse lets users securely store and manage data from multiple sources, and Connectors enable you to connect to apps and data, and devices in the cloud. We will discuss these in detail in the next blog. Stay tuned!

Practitioner’s Guide to Data Science: Streamlining Data Science Solutions using Python, Scikit-Learn, and Azure ML Service Platform by Nasir MirzaIn addition to all the other great work he does for AIS and our clients, Nasir Mirza found the time to put together a comprehensive guide for programmers who wish to pursue AI/ML development. This guide provides practical guidance and examples for how to build a solid conceptual foundation and familiarity with data sciences related processes and frameworks. The Practitioner’s Guide to Data Science: Streamlining Data Science Solutions using Python, Scikit-Learn, and Azure ML Service Platform covers data science concepts, processes, and real-world hands-on use cases.

Nasir has been with AIS for 12 years, supporting and leading many projects across cloud and data, and helping our clients deliver business outcomes. From his deep experience and expertise, he’s provided guidance to help readers learn:

  • Applied context of Data Science during unprecedented growth in the global data
  • Organizing Data Science projects using CRISP-DM and Microsoft TDSP
  • Hands-on and guidelines on Data acquisition, exploration, and analysis
  • Implementation of data pre-processing and Feature Engineering
  • Understanding algorithm selection, model development, and model evaluation
  • Hands-on with Azure ML Service, its architecture, and capabilities
  • Using Azure ML SDK and MLOps for implementing real-world use cases

If you’re interested in growing your career in AI/ML development, or you’re a Software Architect or Manager involved in the design and delivery of data science-based solutions, get your copy today and learn from a seasoned data science professional.

In this blog, we will discuss Kubernetes (aka k8s for short). In this blog, we will cover the following:

  • What is Kubernetes?
  • How is it different from the traditional model?
  • How has Kubernetes evolved?
  • Why would you need k8s?
  • What can k8s do?

In the end, we will walk through setting up a Kubernetes cluster on the Microsoft Azure cloud.

What is Kubernetes

Kubernetes or k8s is an orchestrator to build, deploy, update, and manage containers. A container is a standard unit of software that packages up code and all dependencies, so the application runs quickly and reliably from one computing environment to another.

Container Deployment

Traditional Deployment Era

Traditionally, customers ran applications on physical servers. However, there was no way to define resource boundaries for Apps in a physical server, and this caused resource allocation issues. For example, suppose multiple applications run on a physical server. In that case, there can be instances where one application would take up most of the resources, and as a result, the other applications would underperform. A solution would be to run each application on a different physical server. But this did not scale as resources were underutilized, and it was expensive for organizations to maintain many physical servers.

Virtualized Deployment Era

As a solution, virtualization was introduced. It allows you to run multiple Virtual Machines (VMs) on a single physical server’s CPU. In addition, virtualization will enable applications to be isolated between VMs and provide security as the information of one application cannot be freely accessed by another application.

Virtualization allows better utilization of resources in a physical server and allows better scalability because an application can be added or updated easily, reduces hardware costs, and much more. In addition, with virtualization, you can present a set of physical resources as a cluster of disposable virtual machines.

Each VM is a complete machine running all the components, including its own operating system, on top of the virtualized hardware.

Container Deployment Era

Container engines often referred to as operating-system-level virtualization, are operating systems where the kernel allows multiple isolated instances. Each instance is referred to as a container, virtualization engine. Developers use these to create secure, virtual hosting environments with isolated resources.

Therefore, containers are considered lightweight. Similar to a VM, a container has its own filesystem, the share of CPU, memory, process space, and more. However, as they are decoupled from the underlying infrastructure, they are portable across clouds and OS distributions.

Container Run-Time Engine

To create a microservice ecosystem, software solutions such as container management software, container orchestration software, container networking software, container monitoring software, and service discovery software. There are various Container run time engines available in the market, below are a few popular ones:

There are various Container run time engines available in the market, below are a few popular ones:

  • Containers
  • CRI-O
  • Docker
  • Rocket
  • LXD

Docker container runtime integrates well with the Kubernetes engine of the above Container runtime.

Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services. It also facilitates declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available.

Looking for more information on container orchestration? Check out our blog, A Developer’s Guide to Container Orchestration, Kubernetes, & AKS

Why Do I Need Kubernetes?

Containers are an excellent way to bundle and run your applications. However, you need to manage the containers that run the applications and ensure no downtime in a production environment. For example, another container needs to start if a container goes down. Wouldn’t it be easier if a system handled this behavior?

That’s how Kubernetes comes to the rescue! Kubernetes provides you with a framework to run distributed systems resiliently. It takes care of scaling and failover for your application, provides deployment patterns, and more. For example, Kubernetes can easily manage a canary deployment for your system.

Kubernetes provides you with:

  • Service discovery and load balancing. Kubernetes can expose a container using the DNS name or IP address. Then, if traffic to a container is high, Kubernetes can load balance and distribute the network traffic to stabilize the deployment.
  • Storage orchestration. Kubernetes allows you to automatically mount a storage system of your choice, such as local storage, public cloud providers, and more.
  • Automated rollouts and rollbacks. You can describe the desired state for your deployed containers using Kubernetes, and it can change the actual state to the desired state at a controlled rate. For example, you can automate Kubernetes to create new containers for your deployment, remove existing containers and adopt all their resources to the new container.
  • Automatic bin packing. You provide Kubernetes with a cluster of nodes that it can use to run containerized tasks. Then, you tell Kubernetes how much CPU and memory (RAM) each container needs. As a result, Kubernetes can fit containers onto your nodes to make the best use of your resources.
  • Self-healing. Kubernetes restarts containers that fail, replaces containers, kills containers that don’t respond to your user-defined health check, and doesn’t advertise them to clients until they are ready to serve.
  • Secret and configuration management. Kubernetes let you store and manage sensitive information, such as passwords, OAuth tokens, and SSH keys. You can deploy and update secrets and application configuration without rebuilding your container images or exposing secrets in your stack configuration.

A Kubernetes Cluster is a group of machines (Virtual or physical) running together. There are two types of systems in the k8s cluster a Master and a Worker node. Together, these servers form a Kubernetes cluster and are controlled by the services that make up the Control Plane. As a best practice, the worker node hosts user applications, whereas the Master node hosts all system components. However, the master can host user applications, but it is not recommended.

Kubernetes Master Node Control Plane

Kubernetes Cluster Infrastructure Setup

Below is the architecture diagram set up on the Azure cloud. We will set up a single Vnet and two subnets for easier management. One subnet will host worker nodes, and the other subnet will host the master node. Ubuntu LTS 20.x OS will be used for Master and worker nodes. In addition, we will deploy the Windows 10 system to test our applications.

Virtual Network

Since we are creating a k8s cluster setup for learning purposes, all ports are opened to communicate across subnets. Below are the default ports to communicate across cluster components for enterprise-class clusters.

Control Plane and Worker Nodes

Azure Virtual Network Setup

Here, we create a single Vnet and two subnets thru the Azure portal. I’ve included screenshots below to navigate and submit for creation after logging into https://portal.azure.com.

Create a Virtual Network

Create Virtual Network with IP Addresses

The above step creates one Vnet named aks-vnet with a CIDR of 10.0.0./16. And also creates two subnets, one with a CIDR range of 10.0.1.0/24 by name aks-master-subnet and the other subnet with 10.0.2.0/24 CIDR range by name aks-worker-subnet.

Azure VMs Setup

We will set up three Ubuntu 20 LTS systems for worker nodes, one Ubuntu 20 LTS for the master node, and one for Windows 10. As per official documentation, it is recommended to have 2GB Memory and 2 CPUs. But to get better performance, at least 8GB of Memory and four vCPUs are suggested.

Below table shows – the VM sizes, OS type, and hostnames used in our lab setup.

Azure VMs setup

After logging into the Azure portal thru (https://portal.azure.com), please follow “Virtual machines” à Create à”Virtual machine” and follow the below screenshots. This procedure will create a new master node with 8GB Ram, two vCPUs, and four disks. First, choose subnet “aks-master-subnet.” Next, select “password” as the mode of “authentication type” and provide 12 characters long alphanumeric string with lower n upper case and special characters. Also, allow port 22 for “Public inbound” options, allowing ssh and sftp protocols to connect it to this system.

The same steps need to be followed to create Worker nodes but choose “aks-worker-subnet” to create instances under 10.0.2.0/24 CIDR.

Azure VM Creation

Windows 10 jump server is set up in subnet 10.0.1.0/24, and this instance will be used to test applications deployed onto the k8s cluster. A minor modification is needed to connect to this VM and setup while creating, please follow the below screenshots.

Windows 10 System Setup

By default, the windows system requires Network-level authentication, which requires a domain controller. However, as we set it up for learning purposes, we will disable the NLA.

Error Message while connecting through remote desktop

Follow the below screenshot to disable NLA. Next, select VM, “Jumpserver” à” RUN Command” à”DisableNLA” à”RUN.” Once this is successful, VM needs to restart, this change to take effect.

Disabling NLA configuration

With the above updates to the jumpserver configuration, you will be able to connect thru the “remote desktop connection” utility. Once logged, you can check connectivity to all four systems by using ssh from the command line. It would be best if you got successfully authenticated and logged into master and worker nodes.

Connectivity testing from jump server to nodes

Installing Prerequisite Software

After building the network and systems, we have to update system packages and install the required software on Master and worker nodes. These packages are:

  • Docker
    • CRE – A software responsible for running the containers.
  • kubeadm
    • A CLI tool that will set up the cluster, upgrade and join worker nodes.
  • Kubelet
    • The kubelet is the primary “node agent” that runs on each node and handles node level operations
  • Kubectl
    • A CLI tool – Used to manage k8s cluster through its API Server.

To install these packages, follow the steps mentioned below on Master as well as Worker nodes:

Step 1. We have to do SSH to our virtual machines with the username and password and switch user to superuser by using Sudo.

switch user to superuser

Step 2. Now we will install the Docker package in our machine using the following command:

apt-get update && apt-get install docker.io</li>

 Install the Docker package

Step 3. Update the apt package index and install packages needed to use the Kubernetes apt repository:

apt-get update && apt-get install -y apt-transport-https ca-certificates curl</li>

Update the apt package index

apt-package-index.png" alt="Update the apt package index " width="800" height="134"

Step 4. Add below lines into /etc/docker/daemon.json to declare systemd as cGROUP driver for docker runtime. If the file is not present, you can create it with the below commands.

}
EOF
chmod 600 /etc/docker/daemon.json

Step 5. Download the Google Cloud public signing key:

curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

Step 6. Add the Kubernetes apt repository:

echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | tee /etc/apt/sources.list.d/kubernetes.list

Step 7. Update apt package index, install kubelet, kubeadm, and kubectl, and pin their version:

apt-get update
apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl

Setup Kubernetes Cluster

As we have successfully installed Kubeadm, next we will create a Kubernetes cluster using the following mentioned steps:

Step 8. We have to initialize kubeadm on the master node. This command will check the node for all required dependencies. Once successful, then it will install control plane components. We will set up the k8s cluster on private IPs. Hence, we need to get the private IP of the master node from Azure portal à Virtual Machine à master à networking à NIC Private IP
(Note: Run this command in Master Node only.)

kubeadm init --apiserver-advertise-address=10.0.1.4

The Kubeadm will run multiple preflight checks, create certificates, and build kubeconfig configuration and this step will take 4-6 minutes depending upon the system’s size.

Kubeadm will run multiple preflight checks

Successful k8s cluster creation will generate the below output and print some commands to join worker nodes to this cluster and make kubectl work.
Please note the highlighted part in the below screenshot, which is required to join worker nodes.

requirements to join worker nodes

Master node successful creation output

The above screenshot output shows that cluster is up and running, and the master node is in “Not ready” status. We will have to install CNI to enable communication channels across nodes and Cluster DNS to start functioning. Apply Weave CNI (Container Network Interface) on the master node.

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

Weaver installation and verification of successful pod build

The above command will take a minute to create weaver pods by downloading from weave works, creating weave pods, and bringing coreDNS pods online.

Run below commands as normal user (Non root user to have kubectl connect to K8s cluster)

  • mkdir -p $HOME/.kube</li>
  • sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config</li>
  • sudo chown $(id -u):$(id -g) $HOME/.kube/config</li>

Join Worker Nodes to the Kubernetes Cluster

Our Kubernetes master node is set up, and we should join Worker nodes in our cluster. Perform the following step on all worker nodes as root users or using “sudo.”

kubeadm join 10.0.1.4:6443 --token fajbkz.6fv9xzxeqwkp6n7z --discovery-token-ca-cert-hash sha256:7e7bd6fdfb711c02714d7bafcecc2b48f8bb838b818cffb41845df517e13719d

Also, you can regenerate the above “tokens” and “hash” codes by running the below command on the master node.

kubeadm token create --print-join-command #(On MASTER node only)

The below screenshot shows the successful joining of worker node to cluster. Follow the same procedure on other worker nodes.

Successful worker node joining into k8s cluster

The below screenshot shows the successful k8s cluster with one master node and three worker nodes.

Successful three-node joining into k8s cluster

Conclusion

Kubernetes can be set up in multiple ways depending on your comfortability; I have leveraged kubeadm tool to build a k8 cluster. However, for a better understanding of k8s concepts and to have hands-on. I have opted for the kubeadm tool with one master and 3 worker nodes, which are scalable and single worker nodes.

Alternatively, you may also use minikube to set up an automated, easy and simple tool for building k8s cluster on a single VM in a minimal and automated way.

References: https://kubernetes.io

Every day, too many patients worldwide fall victim to medical problems that can be solved in a matter of a few hundred dollars; a few hundred dollars that they do not have. Donors can help by donating funds to hospitals and support agencies, but they can only hope their money is going straight to where it is needed. Often life-changing surgeries ranging from just a few hundred to a thousand dollars can get lost among the demand for funds to support a wide range of healthcare needs. Watsi tackles this problem head-on.

With a mission to make healthcare a reality for everyone, Watsi is changing lives, and you can, too. Here are six reasons why we support Watsi, and why you should join us:

#1: Watsi hosts crowdfunding of medical treatment for people in need around the world.

Watsi has made history as the first nonprofit to receive financial backing from Silicon Valley’s accelerator Y Combinator. Rather than relying on donations from indirect sources, patients know that money is sent directly to them. A limitless number of donors can fund one treatment, so even a few extra dollars donated translate to a direct impact on patients.

#2: 100% of the donations directly fund medical treatments.

Watsi pays for its operational costs from their funding and none from the donations. They even cover the credit card processing fees. They raise operational funds via accelerators like Y Combinator or angel investors. Think of Watsi as a two-sided market leveraging the internet’s ability to connect donors with needs, a market previously dominated by narrow channels. You can choose to “tip” Watsi for this support, but there is full transparency on where your donations go, with the option to donate 100% to patient care.

Please note, I am not suggesting that using portions of donor contributions for operational costs is bad. Most nonprofits incur considerable operational costs. Yet, the ability to direct 100% of funds patients makes Watsi enticing for many donors like me.

#3: For donors, Watsi enables a “transactional” approach to philanthropy.

Even a few dollars of the contribution goes towards a directed outcome. This can appeal to folks who prefer transactions outcomes over supporting broader initiatives such Against Malaria Foundation or Schistosomiasis Control Initiative. Donors can choose to contribute monthly and will get updates on where their donations are making an impact.

Watsi Monthly Donation

Additionally, because of Watsi’s directed approach, donors can choose to put their donations towards specific causes and treatments they are passionate about, such as heart surgery.

#4: Donors can connect with the people they help.

Because Watsi is run like a startup, as a donor, you have full access to each patient timeline and full access to the transparency report in terms of payments made to the medical providers that Watsi works with. The process of helping someone in need is the most direct it gets, and Watsi makes sure of it. You get an email regarding your initial donation, as well as notifications once they receive treatment with a link to the full story, like Somaly’s story below.

Watsi Donation and Update

#5: This is not just an idea; it’s a success.

After its founding in 2011, Watsi has improved the lives of over 25,000 patients around the world. Here is another story of a little boy in Kenya who suffered from a serious infection.

#6: Watsi provides gift cards, so you can give the gift of giving.

The perfect gift for anyone, you can send a gift card to Watsi via email or mail. The recipient can then donate to any patient or patients they choose and will get updates after they receive care.

Your Donations At Work

AIS has a special culture. As part of a special match campaign by our community, aisGives, who gathers and supports employees in charitable donations, matching, fundraising, volunteering, awareness, we influenced over $20,000 this holiday season. This paid for roughly 50 life-altering surgeries around the world and we’re excited to continue supporting their mission.
SharePoint in Microsoft 365 is a fantastic resource for building company intranets, and a lot of functionality is available without significant customizations.

Even various templates are available through Microsoft’s SharePoint lookbook, showcasing commonly used examples.

One feature missing from the default templates is an announcement banner, a specific request for intranets. For example, companies may want to announce important information to their employees who are prominently featured on the intranet home page, such as an office closure due to weather or a reminder that timesheets are due.

There are examples of how to accomplish this in the SharePoint Patterns and Practices (PnP) GitHub repository (such as react-app-announcements), but this requires the development of a SharePoint Framework (SPFx) application customizer.

However, there is an easier way to display an announcement banner with less effort and without knowledge of SPFx.

A quick summary on how to accomplish this is to:

  • Set up a list in the intranet site to keep track of the announcements
  • Create a custom list view for showing current announcements
  • Use JSON formatting to modify that custom view
  • Place a list view web part on the intranet home page and point it to the custom view

Announcements List Setup

First, set up the announcements list.

From the home page of the intranet, choose “New” > “List” in the menu.

SharePoint Communication site

Then choose “Blank List.” In the dialog that appears, enter the list’s name (“Announcements”), add a description, and un-check the box to show in site navigation. Then press the “Create” button.

Company wide announcements

The new list is created, and the screen is redirected to the default list view.
Columns will need to be added to the list to track when to show the announcements.
Press “+ Add column,” then choose “Date and time.”

Create a Column for Values

In the slide-in panel for “Create a column,” enter and/or choose the following values for the column:

  • Name: Start Date
  • Description: The date that the announcement should begin displaying
  • Type: Date and time
  • Include Time: No
  • Friendly format: No
  • Default value: Today’s date

Apply details in created column

Then press the “Save” button to create the new column.

Next, press “+ Add column,” then choose “Date and time” again to add another column.

This time, enter and/or choose the following values for the column, then press the “Save” button to create the new column:

  • Name: End Date
  • Description: The date that the announcement should stop displaying
  • Type: Date and time
  • Include Time: Yes
  • Friendly format: No
  • Default value: None

Create an End Date Column

Another column to define the type of announcement should also be created. This will also determine the icon and color that is displayed for the announcement.

Press “+ Add column,” then choose “Choice.”

Enter and/or choose the following values for the column:

  • Name: Announcement Type
  • Description: The type of announcement to display: Notice = Blue, Warning = Yellow, Alert = Pink
  • Type: Choice

For the Choices section, edit the existing three choices to be:

  • Notice
  • Warning
  • Alert

Change the color of the “Warning” choice by pressing the palette icon and choosing the “Gold” color.

Change the color of the “Alert” choice by pressing the palette icon and choosing the “Peach” color.

Customize Column Color

Select “Notice” to be the Default value, then press “More options” to make further adjustments to the column.

Choose Options for the Column

Choose the following options for the column, then press “Save” to create it.

  • Display choices using: Radio Buttons
  • Allow multiple selections: No
  • Require that this column contains information: No
  • Enforce unique values: No
  • Add to all content types: Yes

Create a section for a link

The last column to add should be a link if the announcement has more information that the user needs to reference.

Press “+ Add column,” then choose “Single line of text.” Enter and/or choose the following values for the column, then press the “Save” button to create the new column:

  • Name: Announcement Link
  • Description: Link for more information
  • Type: Single line of text
  • Default value: #

Creating an Announcement Column

The Announcements list should now have all the columns needed:

  • Title
  • Start Date
  • End Date
  • Announcement Type
  • Announcement Link

Custom View for Announcements List

Next, a custom view of the Announcements list should be created to display current announcements.

On the right side of the list menu bar, press the “All Items” button, then choose “Create new view”.

New View Creation

In the dialog, enter “Current Announcements” for the View name, keep “Make this a public view” checked, then press “Create.”

Current Announcements

It should redirect to the Current Announcements list view. On the right side of the list menu bar, press the “Current Announcements” button, then choose “Edit current view.”

Edit Current Column View

In the “Columns” section, make sure the following columns are checked, to include them in the view:

  • Title
  • Start Date
  • End Date
  • Announcement Type
  • Announcement Link

Make sure columns are checked

In the “Sort” section, set the first sort to “End Date” and “Show items in descending order,” then set the second sort to “Start Date” and “Show items in descending order.”

Sort the Column by End Date

In the “Filter” section, set the filter to show items when “Start Date” is less than or equal to “[Today]” AND when “End Date” is greater than or equal to “[Today].”

Customize the Filter Section

Scroll down and press the “OK” button to finish editing the view.

Custom View Formatting

Before applying some custom formatting to the view, enter a few items into the list for testing purposes.

To see the items in the view, make sure that for each item, the “Start Date” is less than or equal to today’s date, and the “End Date” is greater than or equal to today’s date. Then, choose at least one of each “Announcement Type” to see how the formatting changes for each type.

An example is below:

  • Title: Timesheets Due by COB 10/31/2021
  • Start Date: 10/26/2021
  • End Date: 11/1/2021 12:00 AM
  • Announcement Type: Warning
  • Announcement Link: #

Timesheets Due and Announcement Link

If the announcement banner should link to somewhere else, enter a full URL into the “Announcement Link” field.

After entering a few items into the list, it should look something like this:

Populated List

On the right side of the list menu bar, press the “Current Announcements” button, then choose “Format current view.”

Current View Format

In the sidebar, scroll down and choose “Advanced mode”.

Advanced Mode

The sidebar will now show an input field that contains JSON code. Copy the code from that field and paste it into a preferred code editor to make it easier to work with.

Format View

Microsoft has some great examples of list view formatting. Let’s walk through the formatting for this example.

Since this view will only show a banner, the list headers and the selection options should be hidden, so “hideSelection” and “hideColumnHeader” should be set to true.

Instead of the traditional table elements, we will use the “rowFormatter” to render custom elements per row/item.

In the row formatter, we should first determine what type the element should be, set by the “elmType” property. In this case, we will set it to a “div”.

Next, we will apply CSS class attributes to that div element based on certain conditions. There are many predefined CSS class names that SharePoint uses, which we can apply to the div. A few of the common ones are listed in their style guidelines.

The condition we want to check is the value of the “Announcement Type” column. When referencing a list column in JSON, enclose it in “[]” brackets, and prepend it with “$”. (Depending on the name of the column, sometimes spaces may also need to be substituted with “_x0020_”.)

In the code snippet shown, we check the following conditions and apply the appropriate CSS classes to the div based on that condition.

Announcement Type

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/row-formatting.schema.json",
  "hideSelection": true,
  "hideColumnHeader": true,
  "rowFormatter": {
    "elmType": "div",
    "attributes": {
      "class": "=if([$AnnouncementType] == 'Notice', 'sp-row-card sp-field-severity--low', if([$AnnouncementType] == 'Warning', 'sp-row-card sp-field-severity--warning', if([$AnnouncementType] == 'Alert', 'sp-row-card sp-field-severity--severeWarning', '')))"
    },
    "children": [
    ]
  }
}

Next, we will specify how the child elements of the div are rendered. Under the “children” property, we will set up two span elements inside the div: One for the icon and one for the text.
For the span element with the icon, first, we set up an “elmType” of “span”. Then we check the “Announcement Type” column again to reference the name of the icon from the Fluent UI library and apply it to the “iconName” attribute under “attributes.”

Attributes

We can also apply specific CSS styles to that span via the “style” property. Here we use custom padding, display, and font-size style attributes.

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/row-formatting.schema.json",
  "hideSelection": true,
  "hideColumnHeader": true,
  "rowFormatter": {
    "elmType": "div",
    "attributes": {
      "class": "=if([$AnnouncementType] == 'Notice', 'sp-row-card sp-field-severity--low', if([$AnnouncementType] == 'Warning', 'sp-row-card sp-field-severity--warning', if([$AnnouncementType] == 'Alert', 'sp-row-card sp-field-severity--severeWarning', '')))"
    },
    "children": [
      {
        "elmType": "span",
        "attributes": {
          "iconName": "=if([$AnnouncementType] == 'Notice', 'Info', if([$AnnouncementType] == 'Warning', 'Error', if([$AnnouncementType] == 'Alert', 'Warning', '')))"
        },
        "style": {
          "padding-right": "12px",
          "display": "inline-block",
          "font-size": "1.5em"
        }
      }
    ]
  }
}

Next to the span with the icon, we will render another span with the “Title” text for that announcement item. It should be set as an “elmType” of “span.” Custom display and vertical-align styles can be applied with the “style” property. To render the title text, set the “txtContent” property to “[$Title]”.

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/row-formatting.schema.json",
  "hideSelection": true,
  "hideColumnHeader": true,
  "rowFormatter": {
    "elmType": "div",
    "attributes": {
      "class": "=if([$AnnouncementType] == 'Notice', 'sp-row-card sp-field-severity--low', if([$AnnouncementType] == 'Warning', 'sp-row-card sp-field-severity--warning', if([$AnnouncementType] == 'Alert', 'sp-row-card sp-field-severity--severeWarning', '')))"
    },
    "children": [
      {
        "elmType": "span",
        "attributes": {
          "iconName": "=if([$AnnouncementType] == 'Notice', 'Info', if([$AnnouncementType] == 'Warning', 'Error', if([$AnnouncementType] == 'Alert', 'Warning', '')))"
        },
        "style": {
          "padding-right": "12px",
          "display": "inline-block",
          "font-size": "1.5em"
        }
      },
      {
        "elmType": "span",
        "style": {
          "display": "inline-block",
          "vertical-align": "top"
        },
        "txtContent": "[$Title]"
      }
    ]
  }
}

Select the code above and copy it. Go back to the editor for the custom view formatting ( “Current Announcements” > “Format current view” > “Advanced mode”) and paste the code into the JSON code editor.

Format View List Layout

Press the “Save” button, and the “Current Announcements” list view should now look similar to this:

List View for Announcements

We may want to change the background color for notices to the same color chosen when creating the choices for the column. To do that, change “sp-field-severity–low” in the div’s class attribute to “sp-CSS-backgroundColor-BgCornflowerBlue.” Once that change is made to the code in the custom view formatting and “Save” is pressed again, any “Notice” announcements should now have a light blue background.

This looks great for basic announcements, but what if users need to link to an article or website for more information? To do that, we will need to take the current span children of each row and move them inside an anchor element used for the link.

Create a new “elmType” of “a” as the first object inside the main div’s “children” property. Set the anchor’s “href” attribute to reference the “Announcement Link” column, and apply a condition to set the anchor’s “target” attribute. We want the link to open in a new window if it is not the default “#” value. Next, add custom “style” properties to set the display, text-align, font-size, text-decoration, and color, then add an empty “children” property, where we will move the current icon and text spans.

{
        "elmType": "a",
        "attributes": {
          "target": "=if([$AnnouncementLink]!='#','_blank','_self')",
          "href": "[$AnnouncementLink]"
        },
        "style": {
          "text-align": "left",
          "font-size": "1.3em",
          "text-decoration": "none",
          "color": "#212121",
          "display": "block"
        },
        "children": []
      }, 

Now move the original child “span” elements into the children of the “a” element. The final code should look like this:

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/row-formatting.schema.json",
  "hideSelection": true,
  "hideColumnHeader": true,
  "rowFormatter": {
    "elmType": "div",
    "attributes": {
      "class": "=if([$AnnouncementType] == 'Notice', 'sp-row-card sp-CSS-backgroundColor-BgCornflowerBlue', if([$AnnouncementType] == 'Warning', 'sp-row-card sp-field-severity--warning', if([$AnnouncementType] == 'Alert', 'sp-row-card sp-field-severity--severeWarning', '')))"
    },
    "children": [
      {
        "elmType": "a",
        "attributes": {
          "target": "=if([$AnnouncementLink]!='#','_blank','_self')",
          "href": "[$AnnouncementLink]"
        },
        "style": {
          "text-align": "left",
          "font-size": "1.3em",
          "text-decoration": "none",
          "color": "#212121",
          "display": "block"
        },
        "children": [
          {
            "elmType": "span",
            "attributes": {
              "iconName": "=if([$AnnouncementType] == 'Notice', 'Info', if([$AnnouncementType] == 'Warning', 'Error', if([$AnnouncementType] == 'Alert', 'Warning', '')))"
            },
            "style": {
              "padding-right": "12px",
              "display": "inline-block",
              "font-size": "1.5em"
            }
          },
          {
            "elmType": "span",
            "style": {
              "display": "inline-block",
              "vertical-align": "top"
            },
            "txtContent": "[$Title]"
          }
        ]
      }
    ]
  }
}

Paste this updated code into the editor for the custom view formatting ( “Current Announcements”
> “Format current view” > “Advanced mode”), and press the “Save” button once again.

Current Announcements

The “Current Announcements” list view should now look similar to this:

Current Announcement Views

Display List View on Home Page

Now that the list view has been formatted as desired, it can be added to the intranet home page.

Go to the intranet home page and press the “Edit” button in the toolbar to edit the page.

Edit Current View

Hover over a prominent area on the page where the announcements should go, then press the “+” button to add a new web part there.

Add new web part

Scroll down to the “Documents, lists, and libraries” section in the menu and choose the “List” web part.

Choose the List web part

When the web part is added to the page, it will prompt for which list to select. Choose the “Announcements” list.

Announcements

By default, the List web part displays the All Items list view. Hover over the pencil icon next to the web part to edit its properties.

Edit Announcements List

In the slide-in panel, select the “Current Announcements” view, toggle the switch to the “Hide command bar,” then press the “Apply” button.

Current Announcements

The List web part should now display the formatted “Current Announcements” view without additional list command bar controls.

Web Part List

In the page toolbar, press the “Save as draft” button to save the updates, then press “Republish” to publish the new version of the home page.

Save as a Draft

Now important company announcements are displayed on the intranet home page in a prominent location.

Republish

Conclusion

This is just one example of how a low-code solution with relatively little effort can be implemented to satisfy the need for a custom feature not natively provided by SharePoint.
For additional resources and other examples, refer to Microsoft’s documentation on list formatting.

AIS has tons of experience helping companies build useful intranets. Contact us to see how we can help.