[{"data":1,"prerenderedAt":764},["ShallowReactive",2],{"\u002Fnext\u002Fdodock\u002Fdeveloppeurs\u002Fconfigurer-une-application-via-ui":3,"section:\u002Fnext\u002Fdodock\u002Fdeveloppeurs\u002Fconfigurer-une-application-via-ui":763},{"id":4,"title":5,"body":6,"description":745,"extension":746,"meta":747,"navigation":428,"path":759,"seo":760,"stem":761,"__hash__":762},"docs\u002F2.next\u002F3.dodock\u002F10.developpeurs\u002Fconfigurer-une-application-via-ui.md","Configurer une application via son propre assistant",{"type":7,"value":8,"toc":734},"minimark",[9,13,22,27,73,80,87,110,117,121,130,192,207,218,224,232,239,341,344,347,376,381,384,638,642,730],[10,11,5],"h1",{"id":12},"configurer-une-application-via-son-propre-assistant",[14,15,16,17,21],"p",{},"Une application peut remplacer l'assistant de configuration du bureau par sa propre interface. Sur un site neuf, le bureau redirige alors l'utilisateur vers cette interface. L'application termine ensuite la configuration par un appel à ",[18,19,20],"code",{},"complete_app_setup",".",[23,24,26],"h2",{"id":25},"prérequis","Prérequis",[28,29,30,37,56,63],"ul",{},[31,32,33,34,21],"li",{},"Une application avec un fichier ",[18,35,36],{},"hooks.py",[31,38,39,40,44,45,48,49,52,53,21],{},"Une page de l'application servie ",[41,42,43],"strong",{},"hors du bureau"," (pas sous ",[18,46,47],{},"\u002Fapp\u002F"," ni ",[18,50,51],{},"\u002Fdesk\u002F","), par exemple une page Vue sous ",[18,54,55],{},"\u002Fsuite\u002Fsetup",[31,57,58,59,62],{},"Un utilisateur avec le rôle ",[41,60,61],{},"System Manager"," pour terminer la configuration.",[31,64,65,66,48,69,72],{},"Aucune application active ne déclare ",[18,67,68],{},"setup_wizard_stages",[18,70,71],{},"setup_wizard_complete"," (voir la section « Choix de l’assistant »).",[23,74,76,77],{"id":75},"_1-déclarer-le-hook-setup_wizard_url","1. Déclarer le hook ",[18,78,79],{},"setup_wizard_url",[14,81,82,83,86],{},"Le hook est une ",[41,84,85],{},"chaîne"," (une route), pas une fonction :",[88,89,94],"pre",{"className":90,"code":91,"language":92,"meta":93,"style":93},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# hooks.py\nsetup_wizard_url = \"\u002Fsuite\u002Fsetup\"\n","python","",[18,95,96,104],{"__ignoreMap":93},[97,98,101],"span",{"class":99,"line":100},"line",1,[97,102,103],{},"# hooks.py\n",[97,105,107],{"class":99,"line":106},2,[97,108,109],{},"setup_wizard_url = \"\u002Fsuite\u002Fsetup\"\n",[14,111,112,113,116],{},"Le modèle d'application généré par ",[18,114,115],{},"bench new-app"," contient cette ligne en commentaire.",[23,118,120],{"id":119},"_2-choix-de-lassistant","2. Choix de l'assistant",[14,122,123,126,127,21],{},[18,124,125],{},"frappe.desk.page.setup_wizard.setup_wizard.get_setup_wizard_url()"," choisit la route. Le résultat est placé dans ",[18,128,129],{},"frappe.boot.setup_wizard_url",[131,132,133,146],"table",{},[134,135,136],"thead",{},[137,138,139,143],"tr",{},[140,141,142],"th",{},"Situation",[140,144,145],{},"Route utilisée",[147,148,149,163,178],"tbody",{},[137,150,151,157],{},[152,153,154,155],"td",{},"Aucune application ne déclare ",[18,156,79],{},[152,158,159,162],{},[18,160,161],{},"\u002Fdesk\u002Fsetup-wizard"," (assistant du bureau)",[137,164,165,174],{},[152,166,167,168,170,171,173],{},"Une application active déclare ",[18,169,68],{}," ou ",[18,172,71],{}," (par exemple ERPNext)",[152,175,176],{},[18,177,161],{},[137,179,180,186],{},[152,181,182,183,185],{},"Une ou plusieurs applications déclarent ",[18,184,79],{},", et aucune ne déclare d'étapes",[152,187,188,189],{},"La route de la ",[41,190,191],{},"dernière application installée",[14,193,194,195,197,198,201,202,170,204,206],{},"Tant que la configuration n'est pas terminée, le routeur du bureau redirige vers ",[18,196,79],{}," avec ",[18,199,200],{},"window.location.replace",". Une route qui commence par ",[18,203,47],{},[18,205,51],{}," ne déclenche pas cette redirection : le bureau ouvre alors son propre assistant.",[208,209,210,211,214,215,217],"mermaid",{},"\nflowchart TD\n    A[Site non configuré] --> B{Une application active déclare",[212,213],"br",{},"setup_wizard_stages ou setup_wizard_complete ?}\n    B -->|Oui| C[\u002Fdesk\u002Fsetup-wizard]\n    B -->|Non| D{Une application déclare",[212,216],{},"setup_wizard_url ?}\n    D -->|Non| C\n    D -->|Oui| E[Route de la dernière application installée]\n    E --> F[Appel à complete_app_setup]\n    F --> G[Site configuré]\n",[23,219,221,222],{"id":220},"_3-terminer-la-configuration-avec-complete_app_setup","3. Terminer la configuration avec ",[18,223,20],{},[88,225,230],{"className":226,"code":228,"language":229,"meta":93},[227],"language-text","POST \u002Fapi\u002Fmethod\u002Ffrappe.desk.page.setup_wizard.setup_wizard.complete_app_setup\n","text",[18,231,228],{"__ignoreMap":93},[14,233,234,235,238],{},"La méthode exécute le moteur de configuration (",[18,236,237],{},"process_setup_stages",") sans les étapes de saisie du bureau : enregistrement de la langue et de la région, puis les étapes de fin.",[131,240,241,254],{},[134,242,243],{},[137,244,245,248,251],{},[140,246,247],{},"Paramètre",[140,249,250],{},"Type",[140,252,253],{},"Description",[147,255,256,271,286,301,316,329],{},[137,257,258,263,265],{},[152,259,260],{},[18,261,262],{},"country",[152,264,85],{},[152,266,267,268],{},"Pays du site, par exemple ",[18,269,270],{},"France",[137,272,273,278,280],{},[152,274,275],{},[18,276,277],{},"currency",[152,279,85],{},[152,281,282,283],{},"Devise, par exemple ",[18,284,285],{},"EUR",[137,287,288,293,295],{},[152,289,290],{},[18,291,292],{},"timezone",[152,294,85],{},[152,296,297,298],{},"Fuseau horaire, par exemple ",[18,299,300],{},"Europe\u002FParis",[137,302,303,308,310],{},[152,304,305],{},[18,306,307],{},"language",[152,309,85],{},[152,311,312,313],{},"Langue, par exemple ",[18,314,315],{},"fr",[137,317,318,323,326],{},[152,319,320],{},[18,321,322],{},"enable_telemetry",[152,324,325],{},"booléen",[152,327,328],{},"Active la télémétrie",[137,330,331,336,338],{},[152,332,333],{},[18,334,335],{},"allow_recording_first_session",[152,337,325],{},[152,339,340],{},"Autorise l'enregistrement de la première session",[14,342,343],{},"Tous les paramètres sont facultatifs. La méthode n'accepte pas d'autres arguments : créez l'entreprise, les utilisateurs ou les autres données de l'application avec vos propres méthodes.",[14,345,346],{},"Comportement :",[28,348,349,363,366,373],{},[31,350,351,352,355,356,358,359,362],{},"La méthode accepte uniquement ",[18,353,354],{},"POST"," et exige le rôle ",[41,357,61],{}," (",[18,360,361],{},"frappe.only_for",").",[31,364,365],{},"Si le site exige l'assistant du bureau, elle lève l'erreur « This site's setup must run through the built-in wizard. ».",[31,367,368,369,372],{},"Si la configuration est déjà terminée, elle retourne ",[18,370,371],{},"{\"status\": \"ok\"}"," sans rien refaire. Un deuxième appel est donc sans effet.",[31,374,375],{},"Si une autre configuration est en cours, elle lève l'erreur « Setup is already in progress. Please try again in a moment. ».",[377,378,380],"h3",{"id":379},"exemple","Exemple",[14,382,383],{},"Depuis une application Vue avec frappe-ui :",[88,385,389],{"className":386,"code":387,"language":388,"meta":93,"style":93},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { createResource } from \"frappe-ui\";\n\nconst completeSetup = createResource({\n    url: \"frappe.desk.page.setup_wizard.setup_wizard.complete_app_setup\",\n    method: \"POST\",\n    onSuccess() {\n        window.location.href = \"\u002Fsuite\";\n    },\n});\n\ncompleteSetup.submit({\n    country: \"France\",\n    currency: \"EUR\",\n    timezone: \"Europe\u002FParis\",\n    language: \"fr\",\n});\n","js",[18,390,391,424,430,452,472,488,500,528,534,545,550,565,581,597,613,629],{"__ignoreMap":93},[97,392,393,397,401,405,408,411,414,418,421],{"class":99,"line":100},[97,394,396],{"class":395},"s7zQu","import",[97,398,400],{"class":399},"sMK4o"," {",[97,402,404],{"class":403},"sTEyZ"," createResource",[97,406,407],{"class":399}," }",[97,409,410],{"class":395}," from",[97,412,413],{"class":399}," \"",[97,415,417],{"class":416},"sfazB","frappe-ui",[97,419,420],{"class":399},"\"",[97,422,423],{"class":399},";\n",[97,425,426],{"class":99,"line":106},[97,427,429],{"emptyLinePlaceholder":428},true,"\n",[97,431,433,437,440,443,446,449],{"class":99,"line":432},3,[97,434,436],{"class":435},"spNyl","const",[97,438,439],{"class":403}," completeSetup ",[97,441,442],{"class":399},"=",[97,444,404],{"class":445},"s2Zo4",[97,447,448],{"class":403},"(",[97,450,451],{"class":399},"{\n",[97,453,455,459,462,464,467,469],{"class":99,"line":454},4,[97,456,458],{"class":457},"swJcz","    url",[97,460,461],{"class":399},":",[97,463,413],{"class":399},[97,465,466],{"class":416},"frappe.desk.page.setup_wizard.setup_wizard.complete_app_setup",[97,468,420],{"class":399},[97,470,471],{"class":399},",\n",[97,473,475,478,480,482,484,486],{"class":99,"line":474},5,[97,476,477],{"class":457},"    method",[97,479,461],{"class":399},[97,481,413],{"class":399},[97,483,354],{"class":416},[97,485,420],{"class":399},[97,487,471],{"class":399},[97,489,491,494,497],{"class":99,"line":490},6,[97,492,493],{"class":457},"    onSuccess",[97,495,496],{"class":399},"()",[97,498,499],{"class":399}," {\n",[97,501,503,506,508,511,513,516,519,521,524,526],{"class":99,"line":502},7,[97,504,505],{"class":403},"        window",[97,507,21],{"class":399},[97,509,510],{"class":403},"location",[97,512,21],{"class":399},[97,514,515],{"class":403},"href",[97,517,518],{"class":399}," =",[97,520,413],{"class":399},[97,522,523],{"class":416},"\u002Fsuite",[97,525,420],{"class":399},[97,527,423],{"class":399},[97,529,531],{"class":99,"line":530},8,[97,532,533],{"class":399},"    },\n",[97,535,537,540,543],{"class":99,"line":536},9,[97,538,539],{"class":399},"}",[97,541,542],{"class":403},")",[97,544,423],{"class":399},[97,546,548],{"class":99,"line":547},10,[97,549,429],{"emptyLinePlaceholder":428},[97,551,553,556,558,561,563],{"class":99,"line":552},11,[97,554,555],{"class":403},"completeSetup",[97,557,21],{"class":399},[97,559,560],{"class":445},"submit",[97,562,448],{"class":403},[97,564,451],{"class":399},[97,566,568,571,573,575,577,579],{"class":99,"line":567},12,[97,569,570],{"class":457},"    country",[97,572,461],{"class":399},[97,574,413],{"class":399},[97,576,270],{"class":416},[97,578,420],{"class":399},[97,580,471],{"class":399},[97,582,584,587,589,591,593,595],{"class":99,"line":583},13,[97,585,586],{"class":457},"    currency",[97,588,461],{"class":399},[97,590,413],{"class":399},[97,592,285],{"class":416},[97,594,420],{"class":399},[97,596,471],{"class":399},[97,598,600,603,605,607,609,611],{"class":99,"line":599},14,[97,601,602],{"class":457},"    timezone",[97,604,461],{"class":399},[97,606,413],{"class":399},[97,608,300],{"class":416},[97,610,420],{"class":399},[97,612,471],{"class":399},[97,614,616,619,621,623,625,627],{"class":99,"line":615},15,[97,617,618],{"class":457},"    language",[97,620,461],{"class":399},[97,622,413],{"class":399},[97,624,315],{"class":416},[97,626,420],{"class":399},[97,628,471],{"class":399},[97,630,632,634,636],{"class":99,"line":631},16,[97,633,539],{"class":399},[97,635,542],{"class":403},[97,637,423],{"class":399},[23,639,641],{"id":640},"dépannage","Dépannage",[131,643,644,657],{},[134,645,646],{},[137,647,648,651,654],{},[140,649,650],{},"Symptôme",[140,652,653],{},"Cause probable",[140,655,656],{},"Action",[147,658,659,675,690,703,716],{},[137,660,661,666,672],{},[152,662,663,664],{},"Le bureau ouvre ",[18,665,161],{},[152,667,167,668,170,670],{},[18,669,68],{},[18,671,71],{},[152,673,674],{},"Retirez cette application, ou utilisez les étapes de l'assistant du bureau",[137,676,677,680,687],{},[152,678,679],{},"Pas de redirection",[152,681,682,683,170,685],{},"La route commence par ",[18,684,47],{},[18,686,51],{},[152,688,689],{},"Utilisez une route hors du bureau",[137,691,692,695,700],{},[152,693,694],{},"Une autre application ouvre son assistant",[152,696,697,698],{},"Deux applications déclarent ",[18,699,79],{},[152,701,702],{},"La dernière application installée l'emporte",[137,704,705,708,713],{},[152,706,707],{},"L'appel retourne une erreur de permission",[152,709,710,711],{},"L'utilisateur n'a pas le rôle ",[41,712,61],{},[152,714,715],{},"Connectez-vous avec un administrateur",[137,717,718,721,727],{},[152,719,720],{},"Pas de redirection sur un site existant",[152,722,723,726],{},[18,724,725],{},"System Settings.setup_complete"," est déjà coché",[152,728,729],{},"Comportement normal : la redirection ne concerne que les sites neufs",[731,732,733],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":93,"searchDepth":100,"depth":106,"links":735},[736,737,739,740,744],{"id":25,"depth":106,"text":26},{"id":75,"depth":106,"text":738},"1. Déclarer le hook setup_wizard_url",{"id":119,"depth":106,"text":120},{"id":220,"depth":106,"text":741,"children":742},"3. Terminer la configuration avec complete_app_setup",[743],{"id":379,"depth":432,"text":380},{"id":640,"depth":106,"text":641},"Permettre à une application de gérer son propre assistant de configuration au lieu d'utiliser celui de Dodock.","md",{"badges":748,"reviewed":428,"last_verified":753,"sources":754},[749],{"type":750,"label":751,"tooltip":752},"dokos","Développement","Fonctionnalité destinée aux développeurs","2026-11-03",[755,756,757,758],"dodock@develop:frappe\u002Fdesk\u002Fpage\u002Fsetup_wizard\u002Fsetup_wizard.py","dodock@develop:frappe\u002Fboot.py","dodock@develop:frappe\u002Fpublic\u002Fjs\u002Ffrappe\u002Frouter.js","dodock@develop:frappe\u002Futils\u002Fboilerplate.py","\u002Fnext\u002Fdodock\u002Fdeveloppeurs\u002Fconfigurer-une-application-via-ui",{"title":5,"description":745},"2.next\u002F3.dodock\u002F10.developpeurs\u002Fconfigurer-une-application-via-ui","h_OwW7LGZ-W8_mtom-tZ8BihdEW5EsoTlGuGeJM1j0Q",{},1793871742738]