Blog

In HTML

css grid-template-columns

On 05/09/2024

Dans un contexte CSS responsive, grid-template-columns est une propriété CSS puissante utilisée avec **CSS Grid Layout** pour définir la disposition des colonnes dans une grille.

Elle permet de spécifier le nombre, la taille et le comportement des colonnes dans un conteneur de grille. Voici une explication détaillée de son fonctionnement avec des exemples variés.

1. **Comprendre `grid-template-columns La propriété grid-template-columns permet de définir la largeur des colonnes dans une grille. Vous pouvez utiliser des unités de mesure variées telles que `px`, `%`, `fr` (fraction), `auto`, et des mots-clés comme `min-content` et `max-content`.

2. **Syntaxe de Base**


grid-template-columns: [valeur] [valeur] ...;

- Chaque valeur dans la liste représente la taille d'une colonne dans la grille. - Les valeurs peuvent être de tailles absolues (`px`, `em`), relatives (`%`), des fractions (`fr`), ou automatiques (`auto`).

3. **Exemples d'Utilisation** # Exemple 1: **Définir des Colonnes de Tailles Fixes**


.container {
  display: grid;
  grid-template-columns: 100px 200px 150px;
}

Dans cet exemple, le conteneur de grille aura trois colonnes de largeurs fixes : 100 pixels, 200 pixels, et 150 pixels respectivement.

# Exemple 2: **Utiliser des Fractions (`fr`)**


.container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
}

- Ici, la grille est divisée en quatre parties égales (`1fr + 2fr + 1fr = 4fr`).

- La première colonne occupe `1/4` de l'espace disponible, la deuxième colonne `2/4` (ou `1/2`), et la troisième colonne `1/4`.

# Exemple 3: **Combiner Tailles Fixes et Fractions**


.container {
  display: grid;
  grid-template-columns: 150px 2fr 1fr;
}

- La première colonne a une largeur fixe de 150 pixels.

- Les colonnes suivantes utilisent la taille fractionnelle, où la deuxième colonne est deux fois plus large que la troisième.

# Exemple 4: **Colonnes Automatiques avec `auto


.container {
  display: grid;
  grid-template-columns: auto auto auto;
}

- Chaque colonne prendra seulement l'espace nécessaire pour s'adapter à son contenu

# Exemple 5: **Utiliser des `minmax()` pour une Grille Responsive**


.container {
  display: grid;
  grid-template-columns: repeat(3, minmax(100px, 1fr));
}

- Utilise la fonction minmax() pour définir la taille minimale et maximale des colonnes.

- Chaque colonne aura une taille minimale de `100px` et peut s'étendre jusqu'à `1fr` (une fraction de l'espace disponible).

# Exemple 6: **Grille Répétée avec `repeat()


.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

- Utilise la fonction repeat() pour créer une grille avec 4 colonnes, chacune occupant une fraction égale (`1fr`) de l'espace disponible.

# Exemple 7: **Grille Auto-Adaptative avec `auto-fit` et `minmax()


.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

- auto-fit remplit automatiquement la grille avec autant de colonnes qu'il peut en fonction de l'espace disponible. - Les colonnes auront une taille minimale de `150px` et s'étendront jusqu'à remplir l'espace disponible (`1fr`).

# Exemple 8: **Mélange de Unités pour une Grille Complexe**


.container {
  display: grid;
  grid-template-columns: 200px 1fr 3fr min-content;
}

- La première colonne a une largeur fixe de `200px`.

- La deuxième colonne utilise `1fr` pour occuper une fraction de l'espace disponible.

- La troisième colonne occupe `3fr`, soit trois fois plus d'espace que la deuxième colonne.

- La dernière colonne prend seulement l'espace nécessaire pour son contenu avec `min-content`.

. **Utilisation de `grid-template-columns` pour des Designs Responsives** Pour créer des mises en page responsives, vous pouvez combiner **CSS Grid** avec des **Media Queries** :


.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px;
}

@media (max-width: 768px) {
  .container {
    grid-template-columns: 1fr;
  }
}

- Sur les écrans plus larges, la grille ajuste le nombre de colonnes en fonction de l'espace disponible, chaque colonne ayant au moins `200px`. - Sur les écrans plus petits (moins de `768px` de large), la grille passe à une seule colonne (`1fr`), ce qui est idéal pour les appareils mobiles.

5. **Conclusion** La propriété grid-template-columns est extrêmement versatile et puissante pour créer des mises en page flexibles et responsives avec CSS Grid. Elle vous permet de contrôler précisément le nombre et la taille des colonnes dans une grille, en s'adaptant aux différents besoins de design et aux tailles d'écran. En combinant cette propriété avec d'autres fonctionnalités CSS comme `minmax()`, `auto-fit`, et `repeat()`, ainsi qu'avec des **Media Queries**, vous pouvez créer des interfaces utilisateur modernes qui s'adaptent de manière fluide à différents appareils et résolutions.

In HTML

SFPXReact_From_Css

On 05/09/2024

#### Introduction
Le développement de composants pour SharePoint Framework (SPFx) en utilisant React nécessite une attention particulière aux pratiques CSS pour garantir que vos interfaces sont responsives et adaptées à tous les types d'écrans, que ce soit sur mobile, tablette ou desktop. 

#### 1. **Principes de Base pour des CSS Responsives**

1. **Unité Relative** :
   - Utilisez des unités relatives comme `%`, `em`, `rem`, `vh`, et `vw` pour les marges, les paddings, et les dimensions. Cela permet aux éléments de s’adapter dynamiquement à la taille de l'écran.

2. **Media Queries** :
   - Utilisez des media queries pour ajuster les styles en fonction de la taille de l'écran. Par exemple, pour les écrans de moins de 768px de largeur (taille de tablette), vous pouvez ajuster les layouts.
   ```css
   @media (max-width: 768px) {
       .container {
           flex-direction: column;
       }
   }
   ```

3. **Flexbox** :
   - Utilisez **Flexbox** pour créer des layouts flexibles qui peuvent s'adapter facilement aux différentes tailles d'écran. Flexbox est particulièrement utile pour les barres de navigation, les formulaires, et les mises en page de cartes.
   ```css


   .form-container {

       display: flex;

       flex-wrap: wrap;

   }

 

   .form-group {
       flex: 1 1 300px; /* Les groupes de formulaire s'ajustent avec un minimum de 300px */
       margin: 10px;
   }
   ```

4. **Grid Layout** :
   - Pour des mises en page plus complexes, comme des tableaux de données ou des calendriers, utilisez **CSS Grid**. Cela permet de contrôler avec précision la disposition des éléments sur la page.

#### 2. **Exemple de Formulaire Responsive**

Voici un exemple de formulaire avec différents types d'entrées HTML, construit en React et avec une mise en page responsive.

##### **HTML/JSX pour le Formulaire**

```jsx
import * as React from 'react';
import './Form.css';

const ResponsiveForm = () => {
    return (
        <form className="form-container">
            <div className="form-group">
                <label htmlFor="name">Nom:</label>
                <input type="text" id="name" name="name" placeholder="Votre nom" />
            </div>
            <div className="form-group">
                <label htmlFor="email">Email:</label>
                <input type="email" id="email" name="email" placeholder="Votre email" />
            </div>
            <div className="form-group">
                <label htmlFor="date">Date:</label>
                <input type="date" id="date" name="date" />
            </div>
            <div className="form-group">
                <label htmlFor="color">Couleur:</label>
                <input type="color" id="color" name="color" />
            </div>
            <div className="form-group">
                <label>Sexe:</label>
                <input type="radio" id="male" name="gender" value="male" />
                <label htmlFor="male">Homme</label>
                <input type="radio" id="female" name="gender" value="female" />
                <label htmlFor="female">Femme</label>
            </div>
            <div className="form-group">
                <label>Langues:</label>
                <input type="checkbox" id="english" name="language" value="english" />
                <label htmlFor="english">Anglais</label>
                <input type="checkbox" id="french" name="language" value="french" />
                <label htmlFor="french">Français</label>
            </div>
            <div className="form-group">
                <label htmlFor="people-picker">Personne:</label>
                <input type="text" id="people-picker" name="people-picker" placeholder="Sélectionner une personne" />
            </div>
            <div className="form-group">
                <button type="submit">Envoyer</button>
            </div>
        </form>
    );
};

export default ResponsiveForm;
```

##### **CSS pour le Formulaire**

```css
.form-container {
    display: flex;
    flex-wrap: wrap;
    margin: 20px;
}

.form-group {
    flex: 1 1 300px;
    margin: 10px;
}

.form-group label {
    display: block;
    margin-bottom: 5px;
}

.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="date"],
.form-group input[type="color"],
.form-group input[type="radio"],
.form-group input[type="checkbox"] {
    width: 100%;
    padding: 8px;
    margin-bottom: 10px;
    box-sizing: border-box;
}

button[type="submit"] {
    background-color: #0078d4;
    color: white;
    padding: 10px 20px;
    border: none;
    cursor: pointer;
}

button[type="submit"]:hover {
    background-color: #005a9e;
}

@media (max-width: 768px) {
    .form-container {
        flex-direction: column;
    }
}
```

##### **Rendu Visuel**

L'utilisation de **Flexbox** ici permet aux groupes de formulaire de se réarranger dynamiquement en fonction de la largeur de l'écran. Sur des écrans larges, les groupes se placent côte à côte, tandis que sur les petits écrans (comme les mobiles), ils s'empilent verticalement.

#### 3. **Exemple de Grille Responsive avec les Jours de la Semaine**

Voici un exemple de grille responsive affichant les jours de la semaine.

##### **HTML/JSX pour la Grille**

```jsx
import * as React from 'react';
import './WeekGrid.css';

const WeekGrid = () => {
    return (
        <div className="week-grid">
            <div className="day">Lundi</div>
            <div className="day">Mardi</div>
            <div className="day">Mercredi</div>
            <div className="day">Jeudi</div>
            <div className="day">Vendredi</div>
            <div className="day">Samedi</div>
            <div className="day">Dimanche</div>
        </div>
    );
};

export default WeekGrid;
```

##### **CSS pour la Grille**

```css
.week-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 10px;
    margin: 20px;
}

.day {
    background-color: #f4f4f4;
    padding: 20px;
    text-align: center;
    font-weight: bold;
    border: 1px solid #ddd;
}

@media (max-width: 768px) {
    .week-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 480px) {
    .week-grid {
        grid-template-columns: 1fr;
    }
}
```

##### **Rendu Visuel**

- **Grille par Défaut** : Les jours de la semaine sont affichés côte à côte sur des écrans larges, en 7 colonnes.
- **Tablette** : La grille passe à 2 colonnes, ce qui permet de voir deux jours par ligne.
- **Mobile** : La grille devient une seule colonne, chaque jour étant affiché dans une ligne distincte.

### Conclusion

Les bonnes pratiques pour des CSS responsives dans le développement SPFx avec React incluent l'utilisation de Flexbox et CSS Grid pour créer des mises en page adaptatives, l'utilisation judicieuse des media queries, et la préférence pour des unités relatives pour la taille des éléments. Ces techniques permettent de créer des interfaces utilisateurs qui sont à la fois élégantes et fonctionnelles sur tous types de dispositifs.

In HTML

Css Best Practices For SPFX React

On 04/09/2024

Créer des CSS responsives pour une solution SPFX (SharePoint Framework) avec React nécessite une approche structurée et l'utilisation de bonnes pratiques. Voici quelques recommandations pour vous aider à y parvenir :

1. Utiliser des Media Queries

Les media queries sont essentielles pour créer des designs responsives. Elles permettent d'appliquer des styles différents en fonction de la taille de l'écran.

@media (max-width: 600px) { .container { flex-direction: column; } }

2. Frameworks CSS Responsive

Utiliser des frameworks CSS comme Bootstrap, Tailwind CSS ou Material-UI peut simplifier la création de designs responsives. Ces frameworks offrent des classes utilitaires et des composants pré-stylisés qui sont déjà responsives.

3. Flexbox et Grid Layout

Utilisez Flexbox et CSS Grid pour créer des mises en page flexibles et responsives.

.container { display: flex; flex-wrap: wrap; } .item { flex: 1 1 100%; } @media (min-width: 600px) { .item { flex: 1 1 50%; } }

4. Variables CSS

Utilisez des variables CSS pour gérer les valeurs récurrentes comme les couleurs, les marges et les tailles de police.

:root { --primary-color: #3498db; --font-size: 16px; } .button { background-color: var(--primary-color); font-size: var(--font-size); }

5. Unités Relatives

Utilisez des unités relatives comme em, rem, % et vw/vh pour créer des designs qui s'adaptent aux différentes tailles d'écran.

.container { width: 90%; max-width: 1200px; margin: 0 auto; }

6. Mobile-First Approach

Adoptez une approche mobile-first en écrivant d'abord les styles pour les petits écrans, puis en utilisant des media queries pour ajuster les styles pour les écrans plus grands.

.container { display: flex; flex-direction: column; } @media (min-width: 600px) { .container { flex-direction: row; } }

7. Utiliser des Composants React Responsive

Il existe des bibliothèques comme react-responsive qui permettent de créer des composants React responsives.

import { useMediaQuery } from 'react-responsive'; const MyComponent = () => { const isMobile = useMediaQuery({ query: '(max-width: 600px)' }); return ( <div className={isMobile ? 'mobile-container' : 'desktop-container'}> {/* Your content here */} </div> ); };

8. Optimiser les Images

Utilisez des images responsives avec les attributs srcset et sizes pour servir des images de différentes tailles en fonction de la résolution de l'écran.

<img src="image.jpg" srcset="image-320w.jpg 320w, image-640w.jpg 640w" sizes="(max-width: 600px) 100vw, 50vw" alt="Responsive Image">

9. Utiliser des Outils de Développement

Utilisez des outils comme les DevTools de Chrome pour tester et déboguer vos designs responsives.

10. Documentation et Tests

Documentez vos styles et testez-les sur différents appareils et navigateurs pour vous assurer qu'ils fonctionnent correctement.

En suivant ces bonnes pratiques, vous pouvez créer des CSS responsives efficaces pour votre solution SPFX avec React, garantissant ainsi une expérience utilisateur optimale sur tous les appareils.

Reccueil Besoin Projet SharePoint

On 04/09/2024

Lors de la phase de recueil des besoins pour une application SharePoint, il est essentiel de poser des questions stratégiques pour bien comprendre les attentes du client, définir le périmètre du projet, et éviter les dépassements de budget ou de calendrier. Voici une liste de questions importantes à poser, organisées par catégorie, pour vous aider à affiner les besoins et rédiger des spécifications fonctionnelles précises.

1. Questions générales sur le projet

Quel est l'objectif principal de cette application ?

Quels problèmes ou besoins spécifiques cherchez-vous à résoudre avec cette application ?

Qui sont les principaux utilisateurs de l'application ?

Y a-t-il des applications ou des systèmes existants que l'application SharePoint devra remplacer ou compléter ?

Avez-vous des exemples de solutions similaires que vous avez utilisées ou que vous aimeriez imiter ?

2. Fonctionnalités principales

Quelles sont les fonctionnalités indispensables de l'application ?

Quelles sont les fonctionnalités secondaires ou souhaitables ?

Y a-t-il des flux de travail spécifiques que vous souhaitez automatiser ?

Quels types de contenu seront gérés (documents, listes, bibliothèques, etc.) ?

Comment souhaitez-vous que les utilisateurs interagissent avec l'application (interface utilisateur, expérience utilisateur) ?

3. Gestion des utilisateurs et permissions

Comment les utilisateurs seront-ils gérés ? Faut-il intégrer des groupes d'utilisateurs existants ?

Quelles permissions spécifiques doivent être définies pour différents types d'utilisateurs ?

Y a-t-il des rôles utilisateurs spécifiques à définir (administrateurs, contributeurs, lecteurs, etc.) ?

4. Intégration et interopérabilité

L'application devra-t-elle s'intégrer avec d'autres systèmes (ERP, CRM, etc.) ou services externes (API, services web) ?

Quels outils ou technologies internes existants doivent être compatibles avec cette application ?

Avez-vous des besoins spécifiques concernant l'importation ou l'exportation de données ?

5. Structure des données

Quelles sont les principales entités de données que l'application doit gérer ?

Comment les données seront-elles organisées (listes SharePoint, bibliothèques de documents, métadonnées) ?

Y a-t-il des exigences spécifiques en matière de recherche, de tri ou de filtrage des données ?

6. Design et expérience utilisateur

Avez-vous des attentes spécifiques en matière de design ou de branding (couleurs, logo, etc.) ?

Souhaitez-vous que l'application soit compatible avec des appareils mobiles ?

Quels sont les critères clés pour l'expérience utilisateur (simplicité, rapidité, accessibilité) ?

7. Performance et évolutivité

Quel est le nombre prévu d'utilisateurs simultanés ?

Quelle est la quantité estimée de contenu que l'application devra gérer (documents, données, etc.) ?

L'application doit-elle être évolutive pour accueillir une augmentation du nombre d'utilisateurs ou de contenu ?

8. Sécurité et conformité

Quelles sont les exigences de sécurité spécifiques pour cette application (chiffrement, audit, etc.) ?

Y a-t-il des réglementations ou des normes de conformité spécifiques à respecter (RGPD, ISO, etc.) ?

Faut-il prévoir des sauvegardes régulières ou des procédures de récupération en cas de sinistre ?

9. Maintenance et support

Qui sera responsable de la maintenance de l'application après son déploiement ?

Avez-vous des exigences pour le support technique (SLA, support 24/7, etc.) ?

Souhaitez-vous une formation pour les utilisateurs finaux ou les administrateurs ?

10. Périmètre et calendrier

Quelles sont les fonctionnalités ou parties du projet qui peuvent être reportées dans une phase ultérieure ?

Quel est le calendrier souhaité pour le déploiement de l'application ?

Y a-t-il des dates limites ou des jalons importants à respecter ?

11. Budget

Quel est le budget alloué pour ce projet ?

Y a-t-il des contraintes budgétaires qui pourraient affecter la portée ou les fonctionnalités de l'application ?

12. Risques et challenges

Voyez-vous des risques ou des défis spécifiques pour ce projet ?

Y a-t-il des points d'incertitude ou des zones grises dans les exigences actuelles ?

13. Feedback et révisions

Comment souhaitez-vous valider les différentes étapes du projet ?

À quelle fréquence souhaitez-vous des réunions ou des rapports d'avancement ?

Conclusion

Ces questions vous permettront de mieux comprendre les besoins du client, de clarifier les attentes, de définir un périmètre clair et de rédiger des spécifications fonctionnelles précises. Assurez-vous de bien documenter les réponses et de valider les points critiques avec le client pour éviter tout malentendu ou ajustement coûteux en cours de projet.

SharePoint Restore File Version

On 03/06/2024

/_api/web/getlist('/sites/MySite/MyDocLib')/items(341)/File/versions/restoreByLabel(versionlabel='5.0')

PowerShell Tips

On 28/05/2024

$String = "François-Demaison!?!#@$%^&*()_+\|}{○<>??/ €$¥£¢ \^$.|?*+()[{ 0123456789"

 

 $String -replace '[^\p{L}\p{Nd}/(/_/_]', '_'

Csom query All Items More than 5000

On 28/05/2024



$url = "https://test.sharepoint.com/sites/monSitte"
# Connect-PnPOnline -Url $url -Interactive
Clear-Host
$listTitle = "EarthStation_Authorisations"
$list = Get-PnPList -Identity "Antenna_Model_Ressources" -ThrowExceptionIfListNotFound

$ctx = Get-PnPContext
$page = $null
$pageNumber = 0;
$rowLimit = 3000
$datas = @();

#get first item
$reqFirst = "<View Scope='RecursiveAll'>
<Query>
    <ViewFields>
        <FieldRef Name='ID' />
    </ViewFields>
    <Where>
    </Where>
    <OrderBy>
        <FieldRef Name='ID' Ascending='TRUE' />
    </OrderBy>
</Query>
<RowLimit>1</RowLimit>
</View>"
$spqQuery = New-Object Microsoft.SharePoint.Client.CamlQuery # $req123 #
$spqQuery.ViewXml = $reqFirst #
$itemki = $list.GetItems($spqQuery); 
$ctx.Load($itemki)
$ctx.ExecuteQuery();

$itemId = $itemki[0].ID

# get last item
$reqFirst = "<View Scope='RecursiveAll'>
<Query>
    <ViewFields>
        <FieldRef Name='ID' />
    </ViewFields>
    <Where>
    </Where>
    <OrderBy>
        <FieldRef Name='ID' Ascending='FALSE' />
    </OrderBy>
</Query>
<RowLimit>1</RowLimit>
</View>"
$spqQuery = New-Object Microsoft.SharePoint.Client.CamlQuery # $req123 #
$spqQuery.ViewXml = $reqFirst #
$itemki = $list.GetItems($spqQuery); 
$ctx.Load($itemki)
$ctx.ExecuteQuery();

$max = $itemki[0].ID

$startDate = Get-Date
. ..\common.ps1
Do {
    $stringBuilder = New-Object System.Text.StringBuilder
  
    
  
    $stringBuilder.Append("<View Scope='RecursiveAll'>") | Out-Null
   
    $stringBuilder.Append("<Query><Where><And><And><Geq><FieldRef Name='Modified' /><Value Type='DateTime'>1900-12-01T19:49:00Z</Value></Geq><Gt><FieldRef Name='ID' /><Value Type='Counter'>$($itemId)</Value></Gt></And><Leq><FieldRef Name='ID' /><Value Type='Counter'>$($itemId + $rowLimit)</Value></Leq></And></Where>") | Out-Null
    # $stringBuilder.Append("<Query><Where><And><And><Geq><FieldRef Name='Modified' /><Value Type='DateTime'>1900-12-01T19:49:00Z</Value></Geq><Gt><FieldRef Name='ID' /><Value Type='Counter'>$($itemId)</Value></Gt></And><Leq><FieldRef Name='ID' /><Value Type='Counter'>$($itemId + $rowLimit)</Value></Leq></And></Where>") | Out-Null
    $stringBuilder.Append("<OrderBy><FieldRef Name='ID' Ascending='TRUE' /></OrderBy>") | Out-Null
    $stringBuilder.Append("</Query>") | Out-Null
   
    $stringBuilder.Append("<ViewFields>") | Out-Null
    $stringBuilder.Append("<FieldRef Name='Title' />") | Out-Null
    $stringBuilder.Append("<FieldRef Name='FileLeafRef' />") | Out-Null
    $stringBuilder.Append("<FieldRef Name='FileRef' />") | Out-Null
    $stringBuilder.Append("<FieldRef Name='Modified' />") | Out-Null
    $stringBuilder.Append("<FieldRef Name='Created' />") | Out-Null
    $stringBuilder.Append("<FieldRef Name='ID' />") | Out-Null
    $stringBuilder.Append("<FieldRef Name='Editor' />") | Out-Null
    $stringBuilder.Append("</ViewFields>") | Out-Null
   
    $stringBuilder.Append("<RowLimit Paged='TRUE'>$($rowLimit)</RowLimit>") | Out-Null
    $stringBuilder.Append("</View>") | Out-Null
     
    $req123 = Get-Content -Path ".\req\req1.xml" -Encoding:UTF8
    $spqQuery = New-Object Microsoft.SharePoint.Client.CamlQuery # $req123 #
    $spqQuery.ViewXml = $stringBuilder.ToString();
    $spqQuery.ListItemCollectionPosition = $page


    $pageNumber ++;

    $itemki = $list.GetItems($spqQuery); 
    $spqQuery.ListItemCollectionPosition = $itemki.ListItemCollectionPosition

    try {
        $ctx.Load($itemki)
        $ctx.ExecuteQuery();
    }
    catch {
        <#Do this if a terminating exception happens#>
        Write-Host "$($_)"
        Write-Host "$($_)"
        exit 0
    }


    Write-Host "################## PAGE " $($page.PagingInfo) " #########################"
    Write-Host "processing query results. Recs: $($itemki.Count) itemId $($itemId) max $($max)"
    
    $Counter = 0;
    foreach ($item in $itemki) {
        # Write-Host "$($item["ID"]) title pageNumber '$($pageNumber)' : $($item["Title"])"
        $datas += [PSCustomObject]@{
            "FileLeafRef" = $item["FileLeafRef"]
            "Title"       = $item["Title"]
            "FileRef"     = $item["FileRef"]
            "Modified"    = $item["Modified"]
            "Created"    = $item["Created"]
            "Editor"    = $item["Editor"].Email
        }
        $itemId = $item.ID
    }

    $page = $itemki.ListItemCollectionPosition
    # $itemId += $rowLimit
}   
Until($itemId -ge $max) 
Write-Host "$($listTitle) list.ItemCount $($list.ItemCount)" 
$datas | Export-Csv -Path ".\datas\$($listTitle)_7.csv" -Encoding utf8 -NoTypeInformation -Delimiter ";" -Append
Write-Host "$(AddNiceTimeSpan -start $startDate)"

SharePoint Copy Files To Library

On 27/05/2024


{
    "siteUrl": "https://tenant.sharepoint.com/sites/fdiSandBox/",
    "targetFolder": "/Shared%20Documents/test",
    "sourceFolder": "C:\\temp\\myFolderr",
    "checkIfFileExists": true,
    "forceOverWrite": false,
    "includeChildFolders": true,
    "copyDates": false,
    "copyAuthor": false,
    "lofFileName": "copyfiles",
    "forbiddenChars": "~,#,%,&,*,{,},\\,:,<,>,?,/,|,",
    "replacementChar": "_"
}


Clear-Host
. .\common.ps1
#get copy configuration
$config = GetConnectionConfiguration -filePath ".\config\configuration.json"
$logFileName = "$($config.lofFileName))_$(Get-Date -Format "yyyyMMddhhmmss").log"
$loadedFolders = @();
$startDate = Get-Date
function CheckAlreadyConnected {
    Param([Parameter (Mandatory = $true)][string]$url)
    $ctx = Get-PnPContext
    if ($null -eq $ctx) {
        Connect-PnPOnline -Url $url -Interactive -ErrorAction Stop
        WriteInfo -Message "connected to $($url)"
    }
    else {
        $web = Get-PnPWeb
        if ($web.Url.Trim().ToLower().trim("/") -ne $url.Trim().ToLower().trim("/")) {
            Disconnect-PnPOnline
            WriteInfo -Message "Disconnect-PnPOnline  $($web.Url)"
            Connect-PnPOnline -Url $url -Interactive -ErrorAction Stop
            WriteInfo -Message "connected to $($url)"
        }
    }
}
CheckAlreadyConnected -url $config.siteUrl
$web = Get-PnPWeb

function copyFileToSp {
    Param([Parameter (Mandatory = $true)][string]$sourceFilePath,
        [Parameter (Mandatory = $true)][string]$destinationPath
        , $created, $modified
    )
    #check target folder exists
    if (-not $loadedFolders.Contains($destinationPath)) {
        $folder = Get-PnPFolder -Url $destinationPath -ErrorAction SilentlyContinue
        if ($null -eq $folder) {
            $datas = $destinationPath.Split("/", [System.StringSplitOptions]::RemoveEmptyEntries)
            $folderName = $datas[$datas.Length - 1];
            $target = $destinationPath.Substring(0, $destinationPath.Length - $folderName.Length - 1)

            Add-PnPFolder -Name $folderName -Folder $target
        }
        $loadedFolders += $destinationPath
    }
    $destination
    $destinationPath
    $Asset = @{}
    $valuesOk = $false
    # modified
    if ($null -ne $modified) {
        $date = Get-Date -Date $modified 
        $Asset.add("Modified", $date.ToString("yyyy-MM-dd HH:mm"))
        $valuesOk = $true;
    }
    # created
    if ($null -ne $created) {
        $date = Get-Date -Date $created 
        $Asset.add("Created", $date.ToString("yyyy-MM-dd HH:mm"))
        $valuesOk = $true;
    }

    if ($valuesOk -eq $true) {    
        $spFile = Add-PnPFile -Path $sourceFilePath -Folder $destinationPath -Values $Asset
    }
    else {        
        $spFile = Add-PnPFile -Path $sourceFilePath -Folder $destinationPath
    }
    $pp = 0;
    $pp ++;
}

if ($config.includeChildFolders) {
    $filesToCopy = Get-ChildItem -LiteralPath $config.sourceFolder -Recurse
}
else {
    $filesToCopy = Get-ChildItem -LiteralPath $config.sourceFolder 
}
$filesToCopy.Length


foreach ($file in $filesToCopy) {
    $file.FullName;
    $file.LastAccessTime
    if ($file.GetType().Name -eq "FileInfo") {
        $filePath = $file.DirectoryName
        $destinationFileName = $filePath.Substring($config.sourceFolder.Length).trim("\").Replace("\", "/")
        $destinationFileName = "$($web.ServerRelativeUrl)/$($config.targetFolder.Trim().Trim("/"))/$($destinationFileName)".Replace("%20", " ").TrimEnd("/")
        Write-Host "dest : '$($destinationFileName)'"
        copyFileToSp -sourceFilePath $file.FullName -destinationPath $destinationFileName -modified $file.LastWriteTime -created $file.CreationTime
    }
}
WriteInfo -Message "nb files / folders added : $($filesToCopy.Length)"
AddNiceTimeSpan -start $startDate