Blog

PowerApps Functions

On 30/09/2022

PowerApps functions

Parse text to number

    Filter('Workflow Tasks'; ID = Value(txtId.Text))

Add datas (listItem)

    Patch(NewVoie;Defaults(NewVoie);{Num_x00e9_rovoie:"0"&LookUp(NewVoie;ID=1).Num_x00e9_rovoie}))

Update context, and forms datas

    SubmitForm(FormBeneficiaires);;ResetForm(FormBeneficiaires);; NewForm(FormBeneficiaires);; UpdateContext({showPopup:false});

        If(IsBlankOrError(SubmitForm(Form1)), Set(saveStatus, "An error occured" & Form1.Error), Set(saveStatus, "Operation succeded"))

Navigate to another form

    Navigate(Page_infos_enregistrements)

Get query string parameter and set a variable

    Set(InitiativeId; Param("ID"))

Getquerystringparam

 

Get a field from your datasource by ID

    First(Filter(Initiatives; ID=1)).Nom

 

And Or Not

Or(And(Radio1.Selected.Value=4; !IsBlank(txtComment.Text));Radio1.Selected.Value<4)

 

Update Lookup Field

Patch(
        ResultatAnalyses;
        First(//here item to update
            Filter(
                ResultatAnalyses;
                Affaire.Id = currentAffaire.ID And Analyse.Id = ThisItem.ID
            )
        );
        {
            Title: "notused";
            Commentaires: txtGalComment.Text;
            Gravite: Rating1.Value;
            Affaire: {//lookup field name
                Id: currentAffaire.ID;//id of lookup
                Value: LookUp(
                    Affaires;//list who contains lookup value
                    ID = currentAffaire.ID;//id of lookup
                    currentAffaire.Title//title of lookup value
                )
            }
        }
    )

Patch Choice

TypeIntervention: {Value: dtvTypeIntervention.Selected.Value}

Execute automate with json

'My workflow'.Run(
	JSON(
		{
			SolutionId: selectedSolution.ID,
			ImageContent: UploadedImage14.Image
		},
		JSONFormat.IncludeBinaryData
	)
);

Reg ex to get cleaned string

Clear(AttachmentsCollection);
ForAll(
      RenameColumns(DataCardValue91.Attachments, "Name", "Name1"),
      Collect(
             AttachmentsCollection,
             Name1
      )
);Set(Title1, First(AttachmentsCollection).Value);Set(FileName1, Concat( Split(First(AttachmentsCollection).Value, "" ), If( IsMatch(Result, "([^A-Za-z0-9\.\-])" ), "",Result ) ))

Save Form

SubmitForm(Form1);;If(!IsBlankOrError( Form1.Error); Notify("Une erreur est survenue lors de la sauvegarde " & Form1.Error; NotificationType.Error);Notify("La savegarde a réussi";NotificationType.Information);;Set(currentElement; Form1.LastSubmit))

 

Sort columns


Set(Month, Distinct(SortByColumns(CurrentMonthMails, "Year", Ascending, "Month", Ascending), Month))

Set date


Set(StartDate, DateAdd(DateTimeValue( Day(Today) &"/"& Month(Today) &"/"& Year(Today) &" 00:00:00"), -30));

Sum


Sum(Filter(CurrentMonthMails, Month = ThisItem.Result ), uniqMails)

 

Javascript Generate PDF

On 01/04/2025

<html>
<head>
<style>
.button {
  background-color: white;
  border: none;
  Border-radius:5px;
  color: black;
  padding: 15px 32px;
 border: 2px solid #008CBA; 
 text-align: center;
  font-weight : bold ;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  top: 38%;
  right: 27%;
  position:absolute;
}
.button:hover {
  background-color: #008CBA;
  color: white;
}
.imagestyle{
    width: 50%;
    margin-left: 20%;
    position: absolute;
    top: -105px;
    display:none;

}
@media print {
@page {
      size:auto;
      margin:.5rem 0;
}
  #printPageButton {
    display: none;
  }
  #imagestyleId{
      display:block;
  }
 [data-automation-id^=QuickLinksWebPart]{
     display: none !important;
  }
  [data-automation-id=TitleTextId]{
     padding-top: 100px;
  }

  [data-automation-id=CanvasSection]{
     top: -140px;
  }
}
</style>
</head>
<body>
<script type="text/javascript">
function generatePdf() {
 const pageTitle = document.title;
 const printTitle = 'Mandate ' + pageTitle;
 document.title = printTitle;
 window.print();
 document.title = pageTitle;
 return false;
}
</script>

<input type="button" class="button" 
id="printPageButton"
value="Generate Mandate" onclick="generatePdf()">
<img src="tlstLogo.png" class="imagestyle" id="imagestyleId"/>

 

</body>
</html>

Sharepoint Rest Compaire 2 Lists Fields

On 25/03/2025


// Fonction pour comparer les champs de deux listes SharePoint
async function compareSharePointLists(urlSite1, urlSite2, ListRelativeUrl1, ListRelativeUrl2) {
    // Fonction auxiliaire pour obtenir les champs de la liste
    async function getListFields(urlSite, ListRelativeUrl) {
        const response = await fetch(`${urlSite}/_api/web/lists/getbytitle('${ListRelativeUrl}')/fields?$select=InternalName,TypeAsString`, {
            method: 'GET',
            headers: {
                'Accept': 'application/json;odata=verbose',
            },
        });

        if (!response.ok) {
            throw new Error(`Error fetching fields for list at ${ListRelativeUrl}: ${response.statusText}`);
        }

        const data = await response.json();
        return data.d.results;
    }

    try {
        // Obtenir les champs des deux listes
        const fields1 = await getListFields(urlSite1, ListRelativeUrl1);
        const fields2 = await getListFields(urlSite2, ListRelativeUrl2);

        // Comparer les champs
        fields1.forEach(field1 => {
            const matchingField = fields2.find(field2 => field2.InternalName === field1.InternalName);

            if (!matchingField) {
                console.log(`Le champ ${field1.InternalName} est manquant dans ${ListRelativeUrl2} de ${urlSite2}`);
            } else if (field1.TypeAsString !== matchingField.TypeAsString) {
                console.log(`Le type de champ ${field1.InternalName} ne correspond pas dans ${ListRelativeUrl2} de ${urlSite2} : ${field1.TypeAsString} vs ${matchingField.TypeAsString}`);
            }
        });

        fields2.forEach(field2 => {
            const matchingField = fields1.find(field1 => field1.InternalName === field2.InternalName);

            if (!matchingField) {
                console.log(`Le champ ${field2.InternalName} type ${field2.TypeAsString} est manquant dans ${ListRelativeUrl1} de ${urlSite1}`);
            }
        });
    } catch (error) {
        console.error('Erreur lors de la comparaison des champs des listes :', error);
    }
}

// Example usage
compareSharePointLists(
'https://test.sharepoint.com/sites/DoceboMigration', 
'https://test2.sharepoint.com/sites/fdiSandBox', 
'testConfiguration',
'fdiTasks');

Sharepoint List Groups And Permissions

On 24/03/2025


// Function to list all SharePoint groups of a site collection with their permission levels
async function listSharePointGroupsWithPermissions(siteUrl, targetDivId) {
    // Check if the siteUrl and targetDivId are provided
    if (!siteUrl || !targetDivId) {
        console.error("Site URL and target div ID must be provided.");
        // L'URL du site et l'ID de la div cible doivent être fournis.
        return;
    }

    // Construct the REST API URL to get the groups
    const groupsEndpoint = `${siteUrl}/_api/web/sitegroups`;

    try {
        // Fetch the groups from the SharePoint site
        const groupsResponse = await fetch(groupsEndpoint, {
            method: 'GET',
            headers: {
                'Accept': 'application/json;odata=verbose',
            },
        });

        // Check if the response is ok
        if (!groupsResponse.ok) {
            throw new Error(`Error fetching groups: ${groupsResponse.statusText}`);
            // Erreur lors de la récupération des groupes :
        }

        // Parse the JSON response
        const groupsData = await groupsResponse.json();
        const groups = groupsData.d.results;

        // Get the target div element
        const targetDiv = document.getElementById(targetDivId);
        if (!targetDiv) {
            throw new Error(`Target div with ID ${targetDivId} not found.`);
            // Div cible avec l'ID introuvable.
        }

        // Clear the target div
        targetDiv.innerHTML = '';
        
        const permsEndpoint = `${siteUrl}/_api/web/roleassignments?$expand=Member/users,RoleDefinitionBindings`;
        const permsResponse = await fetch(permsEndpoint, {
            method: 'GET',
            headers: {
                'Accept': 'application/json;odata=verbose',
            },
        })
        const permsData = await permsResponse.json();
            const roleAssignments = permsData.d.results;
        if (!permsResponse.ok) {
            throw new Error(`Error fetching roleassignments ${group.Title}: ${permsResponse.statusText}`);
            // Erreur lors de la récupération des utilisateurs pour le groupe
        }
        // Iterate through each group and display its information
        for (const group of groups) {
            // Fetch the role assignments for the group
            

            // Fetch the users in the group
            const usersEndpoint = `${siteUrl}/_api/web/sitegroups(${group.Id})/users`;
            const usersResponse = await fetch(usersEndpoint, {
                method: 'GET',
                headers: {
                    'Accept': 'application/json;odata=verbose',
                },
            });

            // Check if the response is ok
            if (!usersResponse.ok) {
                throw new Error(`Error fetching users for group ${group.Title}: ${usersResponse.statusText}`);
                // Erreur lors de la récupération des utilisateurs pour le groupe
            }

            // Parse the JSON response
            const usersData = await usersResponse.json();
            const users = usersData.d.results;

            // Create a div for the group
            const groupDiv = document.createElement('div');
            groupDiv.className = 'group';

            console.log(group.Title);
            // Create a header for the group
            const groupHeader = document.createElement('h3');
            groupHeader.textContent = `Group: ${group.Title}`;
            // Groupe :
            groupDiv.appendChild(groupHeader);

            // Create a list for the permission levels
            console.log("permissionsList", roleAssignments, group);
            const permissionsList = document.createElement('ul');
            roleAssignments.forEach(roleAssignment => {
                if(roleAssignment.PrincipalId == group.Id){
//Description Name
            roleAssignment.RoleDefinitionBindings.results.forEach(RoleDefinitionBinding => {
                    //RoleDefinitionBindings.results
                    const permissionItem = document.createElement('li');
                    permissionItem.textContent = `Permission Level: '${RoleDefinitionBinding.Name}' ${RoleDefinitionBinding.Description}`;
                    // Niveau de permission :
                    permissionsList.appendChild(permissionItem);
            });
                }
            });
            groupDiv.appendChild(permissionsList);

            // Create a list for the users in the group
            const usersList = document.createElement('ul');
            users.forEach(user => {
                const userItem = document.createElement('li');
                userItem.textContent = `User: ${user.Title}`;
                // Utilisateur :
                usersList.appendChild(userItem);
            });
            groupDiv.appendChild(usersList);

            // Append the group div to the target div
            targetDiv.appendChild(groupDiv);
        }
    } catch (error) {
        // Log the error to the console
        console.error(`Error: ${error.message}`);
        // Erreur :

        // Optionally, display the error message in the target div
        const targetDiv = document.getElementById(targetDivId);
        if (targetDiv) {
            targetDiv.innerHTML = `

Error: ${error.message}

`; //

Erreur : } } } // Example usage await listSharePointGroupsWithPermissions('https://test.sharepoint.com/sites/ssss', 'vpc_WebPart.unknown.a90bc6dc-fba2-4b5c-b7e2-f72005f01a14');

Sharepoint json formatting status icons

On 18/03/2025

Spicons


Here are the CSS classes used in JSON column formatting as sp-field-severity:

sp-field-severity--low: This class is used to indicate a low severity level. It typically applies a specific style to represent low urgency or importance1234.

sp-field-severity--good: This class is used to indicate a good or positive status. It applies a style that signifies a favorable condition1234.

sp-field-severity--warning: This class is used to indicate a warning level. It applies a style that signifies caution or a moderate level of urgency1234.

sp-field-severity--severeWarning: This class is used to indicate a severe warning level. It applies a style that signifies a high level of urgency or importance12354.

sp-field-severity--blocked: This class is used to indicate a blocked or critical status. It applies a style that signifies a very high level of urgency or a critical issue12354.

These classes are part of the SharePoint framework and are used to apply consistent styling across different columns based on the severity or status of the data.

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
  "elmType": "div",
  "attributes": {
    "class": "=if(@currentField == 'CheckMark', 'sp-field-severity--good', if(@currentField == 'Completed', 'sp-field-severity--good', if(@currentField == 'Forward', 'sp-field-severity--low', if(@currentField == 'Warning', 'sp-field-severity--warning', if(@currentField == 'Error', 'sp-field-severity--severeWarning', if(@currentField == 'ErrorBadge', 'sp-field-severity--blocked', '')))))) + ' ms-fontColor-neutralSecondary'"
  },
  "children": [
    {
      "elmType": "span",
      "style": {
        "display": "inline-block",
        "padding": "0 4px"
      },
      "attributes": {
        "iconName": "@currentField"
      }
    },
    {
      "elmType": "span",
      "txtContent": "@currentField"
    }
  ]
}




CheckMark
Completed
Error
Warning
Forward
ErrorBadge


Add
AddFriend
Admin
Airplane
Alert
AlignCenter
AlignLeft
AlignRight
Archive
ArrowDown
ArrowLeft
ArrowRight
ArrowUp
Attach
Back
Blocked
Bold
Bookmark
Calendar
Camera
Cancel
Checkbox
CheckboxComposite
CheckboxIndeterminate
Checkmark
ChevronDown
ChevronLeft
ChevronRight
ChevronUp
CircleRing
Clear
Clock
Close
Cloud
Code
CollapseMenu
Color
Comment
Contact
Copy
CreditCard
DataUsage
Delete
Dismiss
Document
Edit
Education
Emoji
Error
ErrorBadge
Event
Favorite
Filter
Flag
Folder
Forward
Gift
Globe
Group
Help
History
Home
Important
Info
Italic
Link
List
Location
Lock
Mail
Map
Megaphone
Mention
Message
More
Music
NavigateBack
NavigateForward
News
Note
Open
Paste
Pause
People
Phone
Photo
Pin
Play
Print
Product
Redo
Refresh
Remove
Reply
Save
Search
Send
Settings
Share
Shop
ShoppingCart
SignOut
Sort
Star
Status
Story
Tag
Task
Trash
Undo
Unlock
Upload
User
Video
View
Warning
Work



PowerShell SharePoint Search Extract File Content

On 12/03/2025


# Parameters
$siteUrl = "https://xxxx.sharepoint.com/sites/xxxx"
$outputFilePath = "report4.txt"
$doclibpath = "/Connectivity"

# Connect to the SharePoint site
Connect-PnPOnline -Url $siteUrl -UseWebLogin

# Initialize the output file
if (Test-Path $outputFilePath) {
    Remove-Item $outputFilePath
}
New-Item -Path $outputFilePath -ItemType File

# Define the search query to find '.url' files
$query = "Path:$($siteUrl)* And FileExtension:url"
$query = "Path:$($siteUrl)$($doclibpath)* And *.url"

# Execute the search query
$searchResults = Submit-PnPSearchQuery -Query $query -ErrorAction Stop -All -TrimDuplicates $true -SelectProperties "Path,FileName"
Write-Host "nb files found $($searchResults.TotalRows)"
# Check if there are any search results
if ($null -eq $searchResults -or $searchResults.TotalRows -eq 0) {
    Write-Host "No '.url' files found in the search results."
    Exit
}

# Initialize a variable to store combined content
$combinedContent = ""
$count = 0;
# Iterate through each search result
foreach ($result in $searchResults.ResultRows) {# ResultRows PrimarySearchResults
    # Get the file URL 
    $fileUrl = $result.Path
    if(-not $result.Path.ToLower().EndsWith(".url")){
        continue;
    }
    $count++;
    # Get the file content
    $fileContent = $null;
    # $fileContent = Get-PnPFileContent -Url $fileUrl -AsString -ErrorAction Stop
    try {
        $fileContent = Get-PnPFile -Url $fileUrl.Replace("https://eutelsatgroup.sharepoint.com", "") -AsString 
    }
    catch {
        Write-Host "File '$($fileUrl)' error. $($_)"
        continue;
    }
    #$fileContent = Get-PnPFile -Url $fileUrl -AsString
    # Check if the file content is null or empty
    if ([string]::IsNullOrEmpty($fileContent)) {
        Write-Host "File '$fileUrl' is empty or null."
        continue
    }

    # Append the file content to the combined content
    $combinedContent += $result.FileName + "`n"
    $combinedContent += $fileUrl + "`n"
    $combinedContent += $fileContent + "`n`n"
}

# Write the combined content to the output file
Add-Content -Path $outputFilePath -Value $combinedContent

# Disconnect from SharePoint Online
Disconnect-PnPOnline

Write-Host "nb files treated: $($count) Combined content written to '$($outputFilePath)'."

Fluent Ui Componants List

On 25/02/2025

Fluent UI Components and Properties

Button

Property Description
text The text to display on the button.
iconProps Properties to pass to the icon.
onClick Callback for when the button is clicked.
disabled Whether the button is disabled.

TextField

Property Description
label The label for the text field.
value The value of the text field.
onChange Callback for when the value changes.
placeholder Placeholder text for the text field.
disabled Whether the text field is disabled.

Dropdown

Property Description
label The label for the dropdown.
options Array of options to display in the dropdown.
selectedKey The key of the selected option.
onChange Callback for when the selected option changes.
placeholder Placeholder text for the dropdown.
disabled Whether the dropdown is disabled.

Checkbox

Property Description
label The label for the checkbox.
checked Whether the checkbox is checked.
onChange Callback for when the checkbox is toggled.
disabled Whether the checkbox is disabled.

Toggle

Property Description
label The label for the toggle.
checked Whether the toggle is checked.
onChange Callback for when the toggle is toggled.
disabled Whether the toggle is disabled.

Modal

Property Description
isOpen Whether the modal is open.
onDismiss Callback for when the modal is dismissed.
isBlocking Whether the modal is blocking.
containerClassName Custom class name for the modal container.

Panel

Property Description
isOpen Whether the panel is open.
onDismiss Callback for when the panel is dismissed.
headerText The text to display in the panel header.
closeButtonAriaLabel The ARIA label for the close button.

DetailsList

Property Description
items Array of items to display in the list.
columns Array of column definitions.
onItemInvoked Callback for when an item is invoked.
selection Selection object to manage selected items.

Icon

Property Description
iconName The name of the icon to display.
style Custom styles for the icon.
className Custom class name for the icon.

Spinner

Property Description
label The label for the spinner.
size The size of the spinner (e.g., 'small', 'medium', 'large').
ariaLive The ARIA live region attribute.

MessageBar

Property Description
messageBarType The type of the message bar (e.g., 'info', 'success', 'warning', 'error').
isMultiline Whether the message bar should display multiple lines.
onDismiss Callback for when the message bar is dismissed.
dismissButtonAriaLabel The ARIA label for the dismiss button.

Sharepoint List get list fields in console

On 20/02/2025


function getUrlParams() {
  const params = new URLSearchParams(window.location.search);
  const urlParams = {};
  for (const [key, value] of params.entries()) {
    urlParams[key] = value;
  }
  return urlParams;
}
async function getSharePointListFields(listId) {
  const apiUrl = `${_spPageContextInfo.webAbsoluteUrl}/_api/web/lists(guid'${listId}')/fields?$select=InternalName&$orderby=InternalName&$filter=Hidden eq false`;

  try {
    const response = await fetch(apiUrl, {
      method: 'GET',
      headers: {
        'Accept': 'application/json;odata=verbose',
        'Content-Type': 'application/json;odata=verbose',
      },
      credentials: 'include', // Include credentials for authenticated requests
    });

    if (!response.ok) {
      throw new Error('Network response was not ok');
    }

    const data = await response.json();
    return data.d.results;
  } catch (error) {
    console.error('Error fetching SharePoint list fields:', error);
    return [];
  }
}
// Usage
const urlParams = getUrlParams();
const listId = urlParams.List;
window.Fields = "";
if (listId) {
  getSharePointListFields(listId).then((fields) => {
    console.log('SharePoint List Fields:', fields);
    // Process the fields as needed
	fields.map((f) => {
	window.Fields += `${f.InternalName}\n`;
		
	});
    console.log(window.Fields);
  });
} else {
  console.error('List ID not found in URL parameters');
}