diff --git a/Sharepoint_ToolBox.ps1 b/Sharepoint_ToolBox.ps1 index 3eb7499..6a2c33f 100644 --- a/Sharepoint_ToolBox.ps1 +++ b/Sharepoint_ToolBox.ps1 @@ -47,7 +47,9 @@ function Validate-Inputs { #region ===== Profile Management ===== function Get-ProfilesFilePath { - $dir = if ($PSScriptRoot) { $PSScriptRoot } else { $PWD.Path } + $dir = if ($script:DataFolder) { $script:DataFolder } + elseif ($PSScriptRoot) { $PSScriptRoot } + else { $PWD.Path } return Join-Path $dir "Sharepoint_Export_profiles.json" } @@ -123,6 +125,33 @@ function Apply-Profile { #endregion +#region ===== Settings ===== + +function Get-SettingsFilePath { + $dir = if ($PSScriptRoot) { $PSScriptRoot } else { $PWD.Path } + return Join-Path $dir "Sharepoint_Settings.json" +} + +function Load-Settings { + $path = Get-SettingsFilePath + if (Test-Path $path) { + try { + $data = Get-Content $path -Raw | ConvertFrom-Json + return $data + } catch {} + } + return [PSCustomObject]@{ dataFolder = "" } +} + +function Save-Settings { + param([string]$DataFolder) + $path = Get-SettingsFilePath + [PSCustomObject]@{ dataFolder = $DataFolder } | + ConvertTo-Json | Set-Content $path -Encoding UTF8 +} + +#endregion + #region ===== Site Picker ===== # All state in $script:_pkl; accessible from any event handler (no closure tricks needed) @@ -431,7 +460,9 @@ function Show-SitePicker { #region ===== Template Management ===== function Get-TemplatesFilePath { - $dir = if ($PSScriptRoot) { $PSScriptRoot } else { $PWD.Path } + $dir = if ($script:DataFolder) { $script:DataFolder } + elseif ($PSScriptRoot) { $PSScriptRoot } + else { $PWD.Path } return Join-Path $dir "Sharepoint_Templates.json" } @@ -2340,7 +2371,7 @@ function filterGroups(){ $form = New-Object System.Windows.Forms.Form $form.Text = "SharePoint Exporter v6.0" -$form.Size = New-Object System.Drawing.Size(700, 810) +$form.Size = New-Object System.Drawing.Size(700, 840) $form.StartPosition = "CenterScreen" $form.FormBorderStyle = "FixedDialog" $form.MaximizeBox = $false @@ -2414,14 +2445,25 @@ $btnBrowse.Text = "Browse..." $btnBrowse.Location = New-Object System.Drawing.Point(558, 146) $btnBrowse.Size = New-Object System.Drawing.Size(82, 26) +$lblDataDir = (& $lbl "Dossier JSON :" 20 178) +$txtDataDir = New-Object System.Windows.Forms.TextBox +$txtDataDir.Location = New-Object System.Drawing.Point(140, 178) +$txtDataDir.Size = New-Object System.Drawing.Size(408, 22) +$txtDataDir.Font = New-Object System.Drawing.Font("Consolas", 9) + +$btnBrowseDataDir = New-Object System.Windows.Forms.Button +$btnBrowseDataDir.Text = "Browse..." +$btnBrowseDataDir.Location = New-Object System.Drawing.Point(558, 176) +$btnBrowseDataDir.Size = New-Object System.Drawing.Size(82, 26) + $sep = New-Object System.Windows.Forms.Panel -$sep.Location = New-Object System.Drawing.Point(20, 182) +$sep.Location = New-Object System.Drawing.Point(20, 212) $sep.Size = New-Object System.Drawing.Size(642, 1) $sep.BackColor = [System.Drawing.Color]::LightGray # ── TabControl ───────────────────────────────────────────────────────────────── $tabs = New-Object System.Windows.Forms.TabControl -$tabs.Location = New-Object System.Drawing.Point(10, 190) +$tabs.Location = New-Object System.Drawing.Point(10, 220) $tabs.Size = New-Object System.Drawing.Size(662, 310) $tabs.Font = New-Object System.Drawing.Font("Segoe UI", 9) @@ -2830,7 +2872,7 @@ $tabs.TabPages.AddRange(@($tabPerms, $tabStorage, $tabTemplates, $tabSearch, $ta # ── Progress bar ─────────────────────────────────────────────────────────────── $progressBar = New-Object System.Windows.Forms.ProgressBar -$progressBar.Location = New-Object System.Drawing.Point(20, 510) +$progressBar.Location = New-Object System.Drawing.Point(20, 540) $progressBar.Size = New-Object System.Drawing.Size(642, 16) $progressBar.Style = "Marquee" $progressBar.MarqueeAnimationSpeed = 0 @@ -2838,11 +2880,11 @@ $progressBar.MarqueeAnimationSpeed = 0 # ── Log ──────────────────────────────────────────────────────────────────────── $lblLog = New-Object System.Windows.Forms.Label $lblLog.Text = "Log :" -$lblLog.Location = New-Object System.Drawing.Point(20, 534) +$lblLog.Location = New-Object System.Drawing.Point(20, 564) $lblLog.Size = New-Object System.Drawing.Size(60, 20) $txtLog = New-Object System.Windows.Forms.RichTextBox -$txtLog.Location = New-Object System.Drawing.Point(20, 554) +$txtLog.Location = New-Object System.Drawing.Point(20, 584) $txtLog.Size = New-Object System.Drawing.Size(642, 208) $txtLog.ReadOnly = $true $txtLog.BackColor = [System.Drawing.Color]::Black @@ -2865,7 +2907,8 @@ $form.Controls.AddRange(@( $lblTenantUrl, $txtTenantUrl, $btnBrowseSites, $lblClientId, $txtClientId, $lblSiteURL, $txtSiteURL, - $lblOutput, $txtOutput, $btnBrowse, + $lblOutput, $txtOutput, $btnBrowse, + $lblDataDir, $txtDataDir, $btnBrowseDataDir, $sep, $tabs, $progressBar, $lblLog, $txtLog @@ -2941,6 +2984,48 @@ $btnBrowse.Add_Click({ if ($dlg.ShowDialog() -eq "OK") { $txtOutput.Text = $dlg.SelectedPath } }) +$btnBrowseDataDir.Add_Click({ + $dlg = New-Object System.Windows.Forms.FolderBrowserDialog + $dlg.Description = "Selectionnez le dossier de stockage des fichiers JSON (profils, templates)" + $dlg.SelectedPath = if ($txtDataDir.Text -and (Test-Path $txtDataDir.Text)) { + $txtDataDir.Text + } else { + if ($PSScriptRoot) { $PSScriptRoot } else { $PWD.Path } + } + if ($dlg.ShowDialog() -eq "OK") { + $txtDataDir.Text = $dlg.SelectedPath + $script:DataFolder = $dlg.SelectedPath + Save-Settings -DataFolder $dlg.SelectedPath + Refresh-ProfileList + $n = (Load-Templates).Count + $lblTplCount.Text = "$n template(s) enregistre(s) -- cliquez pour gerer" + } +}) + +$txtDataDir.Add_Leave({ + $newDir = $txtDataDir.Text.Trim() + if ([string]::IsNullOrWhiteSpace($newDir)) { return } + if (-not (Test-Path $newDir)) { + $res = [System.Windows.Forms.MessageBox]::Show( + "Le dossier '$newDir' n'existe pas. Voulez-vous le creer ?", + "Dossier introuvable", "YesNo", "Question") + if ($res -eq "Yes") { + try { New-Item -ItemType Directory -Path $newDir | Out-Null } + catch { + [System.Windows.Forms.MessageBox]::Show( + "Impossible de creer le dossier : $($_.Exception.Message)", + "Erreur", "OK", "Error") + return + } + } else { return } + } + $script:DataFolder = $newDir + Save-Settings -DataFolder $newDir + Refresh-ProfileList + $n = (Load-Templates).Count + $lblTplCount.Text = "$n template(s) enregistre(s) -- cliquez pour gerer" +}) + $btnBrowseSites.Add_Click({ $tenantUrl = $txtTenantUrl.Text.Trim() $clientId = $txtClientId.Text.Trim() @@ -3768,6 +3853,13 @@ $btnOpenDupes.Add_Click({ #endregion +# ── Initialisation : chargement des settings ─────────────────────────────── +$_settings = Load-Settings +$script:DataFolder = if ($_settings.dataFolder -and (Test-Path $_settings.dataFolder)) { + $_settings.dataFolder +} elseif ($PSScriptRoot) { $PSScriptRoot } else { $PWD.Path } +$txtDataDir.Text = $script:DataFolder + Refresh-ProfileList $n = (Load-Templates).Count $lblTplCount.Text = "$n template(s) enregistre(s) -- cliquez pour gerer" diff --git a/TODO.md b/TODO.md index 800fd96..0e50f81 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,4 @@ # Features à ajouter : - Sauvegarde du contexte d'authentification en plus des profils - Possibilité de demander la liste de site auquels un user precis a acces -- Possibilité de faire des recherches de fichiers avec pleins de parametres (exemple : Date d'ajout, de modification, extension de fichier, crée par $user, modifié par $user, regex) - Copie de site à site \ No newline at end of file