Modified - Converted the organization creation page to a modal-style dialog and preserved the caller page for cancel.
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled

This commit is contained in:
2026-05-06 14:56:11 +00:00
parent ba0da47957
commit 5338d5f7f6
14 changed files with 528 additions and 86 deletions
+7 -1
View File
@@ -4,6 +4,12 @@ Acest fisier este memoria persistenta Codex pentru acest proiect.
Istoric complet al modificarilor: vezi `./.codex-history.md`.
Baza structurala folosita pentru acest context: `./.ai-structure.md`.
## Documente persistente de orientare
- Pentru harta structurala bruta a repo-ului, foloseste `./.ai-structure.md`.
- Pentru analiza persistenta a fluxurilor principale, a autentificarii si a punctelor uzuale de extensie, foloseste `./.codex-project-map.md`.
- Pentru reluarea rapida dupa un task blocat, ordinea recomandata este: `./.codex-context.md` -> `./.codex-project-map.md` -> `./.codex-history.md` -> fisierele concrete ale taskului.
## Arhitectura generala
- Entry point-ul principal este `main.go`, care seteaza versiunea aplicatiei in `setting.AppVer` si porneste comenzile din `cmd/`.
@@ -70,5 +76,5 @@ Baza structurala folosita pentru acest context: `./.ai-structure.md`.
## Observatii utile
- Versiunea implicita a aplicatiei in build-ul din sursa curenta este `development`, definita in `main.go` si copiata in `setting.AppVer`.
- Pentru istoricul persistent din `.codex-history.md`, foloseste versiunea derivata din repository pentru build-ul curent: `v.1.27.0-dev-38-g4b334df6d4`.
- Pentru istoricul persistent din `.codex-history.md`, foloseste versiunea derivata din repository pentru build-ul curent: `v1.27.0-dev-91-gba0da47957`.
- Structura proiectului separa clar entrypoint-urile, routing-ul, modelele, serviciile si template-urile, ceea ce face extinderile viitoare predictibile.
+23
View File
@@ -503,3 +503,26 @@ Project Change ID[date-time] - application-version - Type - Summary:
- 1 - I updated `templates/org/create.tmpl` so `/org/create` now renders as a visible `ui small modal` dialog with header, content, and actions matching the visual structure used by the Actions secrets and variables modals.
- 2 - I extended `web_src/css/org.css` with page-scoped layout rules that center the active modal on the standalone page while keeping the styling limited to `page-content.organization.new.org`.
- 3 - I updated `routers/web/org/org.go` so `Cancel` now returns to a safe current-site `redirect_to` target or same-site referrer instead of always forcing `/user/settings/organization`, regenerated template bindata, and re-verified the `routers/web/org` package.
98 - [2026-05-06 02:02:33] - v1.27.0-dev-91-gba0da47957 - Type: Added - Added persistent Codex project-orientation documents for fast task handoff and recovery.
- 1 - I added `.codex-project-map.md` as a durable project guide that captures the web request flow, authentication architecture, practical extension points, and a restart procedure for new tasks.
- 2 - I modified `.codex-context.md` so it now points explicitly to `.codex-project-map.md` and documents the recommended read order for resuming work after a blocked session.
- 3 - I refreshed the repository-derived version reference in `.codex-context.md` so future history updates can use the current application version format consistently.
99 - [2026-05-06 02:18:58] - v1.27.0-dev-91-gba0da47957 - Type: Modified - Reworked organization creation into a real overlay modal on top of the organization settings page and made outside clicks close it.
- 1 - I modified `templates/user/settings/organization.tmpl` so the `New Organization` action now opens the create dialog with the standard `show-modal` flow while keeping the organization settings page visible in the background.
- 2 - I converted `templates/org/create.tmpl` into a reusable modal partial and updated `routers/web/org/org.go` so `/org/create` now renders the same organization settings page with that modal auto-opened, preserving `CancelLink` for close and validation-error flows.
- 3 - I simplified `web_src/css/org.css` to keep only the create-modal helper text styling and removed the previous fake standalone modal layout that replaced the background page.
100 - [2026-05-06 10:13:49] - v1.27.0-dev-91-gba0da47957 - Type: Fixed - Corrected the organization settings cancel-link build regression.
- 1 - I fixed `routers/web/user/setting/profile.go` so it uses the `ctx.Req.RequestURI` field instead of calling it like a function.
- 2 - This removes the compile error in `code.gitea.io/gitea/routers/web/user/setting` that was blocking the Windows build after the organization-create modal refactor.
101 - [2026-05-06 10:54:10] - v1.27.0-dev-91-gba0da47957 - Type: Modified - Made the new-organization modal open in place from the UI and reset its default values consistently.
- 1 - I moved the reusable `create-org-modal` inclusion to `templates/base/footer.tmpl` so signed-in users who can create organizations have the modal available on normal pages without navigating away first.
- 2 - I updated the `New Organization` triggers in `templates/base/head_navbar.tmpl`, `templates/user/dashboard/navbar.tmpl`, `templates/admin/org/list.tmpl`, and `templates/user/settings/organization.tmpl` to use `show-modal` with `/org/create` as a non-JavaScript fallback, preserving the current page and scroll position when JavaScript is enabled.
- 3 - I added explicit reset attributes for organization name, `redirect_to`, visibility radios, and the `repo_admin_change_team_access` checkbox so the modal opened from `/user/settings/organization` now uses the same defaults as the one opened from the global create menu.
102 - [2026-05-06 10:55:13] - v1.27.0-dev-91-gba0da47957 - Type: Modified - Extended the in-place new-organization modal behavior to the dashboard organization list component.
- 1 - I modified `web_src/js/components/DashboardRepoList.vue` so the `New Organization` trigger in the organizations dashboard tab now also uses the shared `show-modal` flow instead of forcing navigation when JavaScript is enabled.
- 2 - I kept `/org/create` as the fallback `href` in the component so the non-JavaScript path remains available.
+323
View File
@@ -0,0 +1,323 @@
# Gitea Project Map for Codex
Acest fisier este ghidul persistent pentru orientare rapida in proiect atunci cand un task nou porneste fara contextul sesiunii anterioare.
Ordinea recomandata de citire pentru un task nou:
- `./.codex-context.md`
- `./.codex-project-map.md`
- `./.ai-structure.md`
Cand proiectul se schimba semnificativ, actualizeaza acest fisier impreuna cu `./.codex-context.md`.
## 1. Harta rapida a proiectului
- Entry point executabil: `main.go`
- CLI si lifecycle: `cmd/`
- Initializare aplicatie instalata si montare route tree: `routers/init.go`
- Rute web SSR: `routers/web/`
- Rute API: `routers/api/`
- Context request, sesiune, template data, helpere de raspuns: `services/context/`
- Business logic: `services/`
- Persistenta si modele de domeniu: `models/`
- Infrastructura transversala: `modules/`
- Template-uri server-side: `templates/`
- Frontend browser-side: `web_src/`
## 2. Fluxul complet al unui request web
### 2.1 Bootstrap aplicatie
1. `main.go`
- Seteaza `setting.AppVer`, `setting.AppBuiltWith` si `setting.AppStartTime`.
- Porneste aplicatia CLI prin `cmd.NewMainApp(...)` si `cmd.RunMainApp(...)`.
2. `cmd/web.go`
- `newWebCommand()` defineste comanda `web`.
- `runWeb(...)` pregateste managerul de graceful shutdown.
- `serveInstalled(...)` apeleaza `routers.InitWebInstalled(...)` si apoi `routers.NormalRoutes()`.
3. `routers/init.go`
- `InitWebInstalled(...)` initializeaza Git, settings, storage, cache, DB, modele, auth, indexere, webhook-uri, SSH, actions, cron.
- `NormalRoutes()` monteaza:
- `/` -> `routers/web.Routes()`
- `/api/v1` -> API public
- `/api/internal` -> API privat
- optional `/api/packages`, `/v2`, `/api/actions`, `/api/actions_pipeline`
### 2.2 Pipeline request web
1. `routers/web/web.go:Routes()`
- Construieste routerul web principal.
- Expune asset-uri statice, avatar-uri, `robots.txt`, `metrics`, `healthz`.
2. Middleware de baza
- `common.MustInitSessioner()` pregateste sesiunea.
- `context.Contexter()` construieste contextul web si datele pentru template.
- `newWebAuthMiddleware()` rezolva autentificarea optionala sau obligatorie.
3. `services/context/`
- `NewBaseContext(...)` creeaza baza request-ului.
- `NewWebContext(...)` ataseaza `Doer`, `Repo`, `Org`, `Session`, `Flash`, `PageData`.
- `Contexter()` injecteaza:
- `Link`
- `PageData` pentru JavaScript
- cookie flash
- `SystemConfig`
- date globale pentru template
4. Validare auth si acces
- `verifyAuthWithOptions(...)` impune:
- `SignInRequired`
- `SignOutRequired`
- `AdminRequired`
- protectie cross-origin
- reguli pentru user inactiv sau obligat sa schimbe parola
5. Handler de domeniu
- Request-ul ajunge in `routers/web/...` sau `routers/api/...`
- Handler-ele ar trebui sa ramana subtiri si sa delege logica in `services/...`
6. Business logic si persistenta
- `services/...` orchestreaza regulile de business.
- `models/...` citesc sau scriu in DB si reprezinta starea de domeniu.
- `modules/...` ofera infrastructura reutilizabila: git, storage, cache, markup, log, web, ssh, indexer etc.
7. Raspuns
- Web:
- template din `templates/...`
- plus `PageData` pentru codul din `web_src/js/...`
- API:
- JSON sau fisiere servite prin helperii din `services/context/base.go`
## 3. Analiza detaliata a autentificarii
### 3.1 Unde sunt declarate rutele
Rutele de auth sunt concentrate in `routers/web/web.go`, in special:
- `/user/login`
- `/user/sign_up`
- `/user/two_factor/...`
- `/user/webauthn/...`
- `/user/openid/...`
- `/login/oauth/...`
- `/user/settings/security/...`
- `/user/settings/applications/oauth2/...`
### 3.2 Fisierele-cheie
- `routers/web/auth/auth.go`
- login clasic
- signup
- remember-cookie
- redirect dupa login
- ramificare spre 2FA sau WebAuthn
- `routers/web/auth/password.go`
- forgot password
- reset password
- forced password change
- `routers/web/auth/2fa.go`
- TOTP
- scratch codes
- `routers/web/auth/webauthn.go`
- passkeys
- challenge / assertion pentru login WebAuthn
- `routers/web/auth/openid.go`
- OpenID sign-in
- connect
- register
- `routers/web/auth/oauth.go`
- start si callback pentru provideri OAuth2 / OIDC
- link account
- auto registration
- sync profil / grupuri / eventual chei SSH
- `routers/web/auth/oauth_signin_sync.go`
- sincronizari post-login pentru date din provider
- `routers/web/auth/oauth2_provider.go`
- Gitea ca OAuth2 / OIDC provider
- authorize, access token, userinfo, introspection, JWKS
- `routers/web/auth/linkaccount.go`
- asociere cont extern cu utilizator local
### 3.3 Cum functioneaza login-ul web clasic
1. Browserul intra pe `/user/login`.
2. `context.Contexter()` pregateste request context-ul.
3. `newWebAuthMiddleware()` incearca auth prin:
- OAuth2 header/bearer unde e permis
- Basic auth unde e permis
- reverse proxy auth daca e activ
- sesiune
- SSPI pe Windows daca e activ
4. `auth.SignIn` afiseaza pagina.
5. `POST /user/login` intra in `auth.SignInPost`.
6. Daca autentificarea reuseste:
- poate devia spre 2FA
- poate devia spre WebAuthn
- poate crea remember cookie
- poate redirectiona spre `redirect_to` sau locatie implicita
7. Daca userul este inactiv, blocat sau obligat sa schimbe parola, `verifyAuthWithOptions(...)` sau logica auth opresc fluxul normal.
### 3.4 Rolul `services/auth/`
`services/auth/` contine mecanismele de autentificare reutilizabile folosite de middleware:
- `Basic`
- `OAuth2`
- `Session`
- `ReverseProxy`
- `SSPI`
Ideea importanta: routerul nu face direct toata autentificarea, ci foloseste un grup de strategii compus in `newWebAuthMiddleware()`.
### 3.5 Rolul template-urilor si frontend-ului pentru auth
- UI-ul pentru auth este in `templates/user/auth/`
- JavaScript specific WebAuthn este in `web_src/js/features/user-auth-webauthn.ts`
- CAPTCHA este sustinut atat in template-uri, cat si in `web_src/js/features/captcha.ts`
### 3.6 Unde extinzi fluxul de auth
Pentru:
- un nou pas UI de auth:
- `routers/web/auth/...`
- `templates/user/auth/...`
- optional `web_src/js/features/...`
- o noua regula de autentificare sau o noua sursa:
- `services/auth/...`
- eventual `models/auth/...`
- apoi integrare in `newWebAuthMiddleware()`
- un nou endpoint OAuth2/OIDC provider:
- `routers/web/auth/oauth2_provider.go`
- `services/oauth2_provider/...`
## 4. Ghid practic: unde modifici ce
### 4.1 Ruta web noua
- Handler nou in `routers/web/<domeniu>/`
- Inregistrare in `routers/web/web.go`
- Daca are UI:
- template in `templates/...`
- optional JS/CSS in `web_src/...`
### 4.2 Ruta API noua
- Handler in `routers/api/v1/...` sau subtree-ul API potrivit
- Montare prin `routers/init.go` sau routerul API deja existent
- Pentru validare si raspuns consistent, foloseste helper-ele din `services/context/`
### 4.3 Regula noua de business
- Orchestrare in `services/<domeniu>/`
- Persistenta in `models/<domeniu>/`
- Routerul trebuie sa decida cat mai putin
### 4.4 Date noi in template
- Pune datele specifice paginii in handler sau in middleware-ul de domeniu
- Pune datele globale doar daca sunt cu adevarat cross-cutting
- Pentru date consumate de JS in pagina, foloseste `ctx.PageData`
### 4.5 Ecran nou sau schimbare UI SSR
- Template in `templates/...`
- Daca exista interactiune client-side:
- logica in `web_src/js/features/...`
- stiluri in `web_src/css/...`
### 4.6 Middleware sau comportament global
- Fluxul web global: `routers/web/web.go`
- Context request si helperi de raspuns: `services/context/`
- Middleware comun sau policy comun: `routers/common/` si `modules/web/...`
### 4.7 Functionalitate noua in repo, user, org, admin
- Repo:
- `routers/web/repo/`
- `services/repository/`, `services/pull/`, `services/issue/`, `services/git/`
- `templates/repo/`
- User:
- `routers/web/user/`
- `services/user/`
- `templates/user/`
- Org:
- `routers/web/org/`
- `services/org/`
- `templates/org/`
- Admin:
- `routers/web/admin/`
- adesea cu suport in `models/`, `services/`, `modules/setting/`
- `templates/admin/`
## 5. Puncte de intrare utile pentru taskuri frecvente
- Login / signup / account recovery:
- `routers/web/auth/`
- `templates/user/auth/`
- `services/auth/`
- `models/auth/`
- `models/user/`
- User settings / security / applications:
- `routers/web/user/setting/`
- `templates/user/settings/`
- Repository header / tabs / page chrome:
- `templates/repo/header.tmpl`
- `templates/repo/navbar.tmpl`
- `templates/repo/sub_menu.tmpl`
- Top navigation / global links:
- `templates/base/head_navbar.tmpl`
- `templates/custom/`
- Packages:
- `routers/api/packages/`
- `services/packages/`
- `models/packages/`
- Actions:
- `routers/api/actions/`
- `routers/web/repo/actions/`
- `services/actions/`
- `models/actions/`
## 6. Testare si verificare orientata pe zona schimbata
- Pentru Go:
- `make fmt`
- `make lint-go`
- testul sau pachetul relevant
- Pentru TypeScript:
- `make lint-js`
- `make test-frontend` sau testele tintite relevante
- Pentru modificari de `go.mod`:
- `make tidy`
## 7. Regula de reluare dupa task blocat
Pentru un task nou care continua munca anterioara:
1. Citeste `./.codex-context.md` pentru rezumatul proiectului si regulile persistente.
2. Citeste `./.codex-project-map.md` pentru harta de implementare si punctele de extensie.
3. Citeste `./.codex-history.md` pentru ultimele schimbari reale din proiect.
4. Abia apoi exploreaza fisierele concrete implicate de noul task.
Aceasta ordine ar trebui sa reduca nevoia de a reconstrui manual contextul de fiecare data.
+1 -1
View File
@@ -1 +1 @@
aab373ab6d6705fd6044ef30ecba0d9a07c58f1f
e3591b59f1c56991f10b6f23203f3c9965823eee
+42 -2
View File
@@ -11,10 +11,11 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/modules/httplib"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/context"
@@ -23,7 +24,7 @@ import (
const (
// tplCreateOrg template path for create organization
tplCreateOrg templates.TplName = "org/create"
tplCreateOrg templates.TplName = "user/settings/organization"
)
func getCreateOrgCancelLink(ctx *context.Context) string {
@@ -46,6 +47,35 @@ func getCreateOrgCancelLink(ctx *context.Context) string {
return setting.AppSubURL + fallback
}
func loadOrganizationSettingsPageData(ctx *context.Context) bool {
ctx.Data["PageIsSettingsOrganization"] = true
opts := organization.FindOrgOptions{
ListOptions: db.ListOptions{
PageSize: setting.UI.Admin.UserPagingNum,
Page: ctx.FormInt("page"),
},
UserID: ctx.Doer.ID,
IncludeVisibility: structs.VisibleTypePrivate,
}
if opts.Page <= 0 {
opts.Page = 1
}
orgs, total, err := db.FindAndCount[organization.Organization](ctx, opts)
if err != nil {
ctx.ServerError("FindOrgs", err)
return false
}
ctx.Data["Orgs"] = orgs
pager := context.NewPagination(total, opts.PageSize, opts.Page, 5)
pager.AddParamFromRequest(ctx.Req)
ctx.Data["Page"] = pager
return true
}
// Create render the page for create organization
func Create(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("new_org")
@@ -54,7 +84,12 @@ func Create(ctx *context.Context) {
return
}
if !loadOrganizationSettingsPageData(ctx) {
return
}
ctx.Data["CancelLink"] = getCreateOrgCancelLink(ctx)
ctx.Data["ShowCreateOrgModal"] = true
ctx.Data["visibility"] = setting.Service.DefaultOrgVisibilityMode
ctx.Data["repo_admin_change_team_access"] = true
@@ -71,7 +106,12 @@ func CreatePost(ctx *context.Context) {
return
}
if !loadOrganizationSettingsPageData(ctx) {
return
}
ctx.Data["CancelLink"] = getCreateOrgCancelLink(ctx)
ctx.Data["ShowCreateOrgModal"] = true
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplCreateOrg)
return
+3
View File
@@ -197,6 +197,9 @@ func DeleteAvatar(ctx *context.Context) {
func Organization(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings.organization")
ctx.Data["PageIsSettingsOrganization"] = true
ctx.Data["CancelLink"] = ctx.Req.RequestURI
ctx.Data["visibility"] = setting.Service.DefaultOrgVisibilityMode
ctx.Data["repo_admin_change_team_access"] = true
opts := organization.FindOrgOptions{
ListOptions: db.ListOptions{
+11 -1
View File
@@ -3,7 +3,17 @@
<h4 class="ui top attached header">
{{ctx.Locale.Tr "admin.orgs.org_manage_panel"}} ({{ctx.Locale.Tr "admin.total" .Total}})
<div class="ui right">
<a class="ui primary tiny button" href="{{AppSubUrl}}/org/create">{{ctx.Locale.Tr "admin.orgs.new_orga"}}</a>
<a
class="ui primary tiny button show-modal"
href="{{AppSubUrl}}/org/create"
data-modal="#create-org-modal"
data-modal-org_name.value=""
data-modal-redirect_to.value="{{.Req.RequestURI}}"
data-modal-create-org-visibility-public.checked="true"
data-modal-create-org-visibility-limited.checked="false"
data-modal-create-org-visibility-private.checked="false"
data-modal-create-org-repo-admin-change-team-access.checked="true"
>{{ctx.Locale.Tr "admin.orgs.new_orga"}}</a>
</div>
</h4>
<div class="ui attached segment">
+5
View File
@@ -8,6 +8,11 @@
{{template "custom/body_inner_post" .}}
</div>
{{template "custom/body_outer_post" .}}
{{if .SignedUser}}
{{if .SignedUser.CanCreateOrganization}}
{{template "org/create" .}}
{{end}}
{{end}}
{{template "base/footer_content" .}}
{{ScriptImport "js/index.js" "module"}}
{{template "custom/footer" .}}
+11 -1
View File
@@ -79,7 +79,17 @@
</a>
{{end}}
{{if .SignedUser.CanCreateOrganization}}
<a class="item" href="{{AppSubUrl}}/org/create">
<a
class="item show-modal"
href="{{AppSubUrl}}/org/create"
data-modal="#create-org-modal"
data-modal-org_name.value=""
data-modal-redirect_to.value="{{.Req.RequestURI}}"
data-modal-create-org-visibility-public.checked="true"
data-modal-create-org-visibility-limited.checked="false"
data-modal-create-org-visibility-private.checked="false"
data-modal-create-org-repo-admin-change-team-access.checked="true"
>
{{svg "octicon-organization"}} {{ctx.Locale.Tr "new_org"}}
</a>
{{end}}
+50 -56
View File
@@ -1,63 +1,57 @@
{{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content organization new org">
<div class="ui container">
<div class="org-create-modal-wrap">
<div class="ui small modal active">
<a class="inside close icon" href="{{.CancelLink}}">{{svg "octicon-x" 16}}</a>
<div class="header">{{ctx.Locale.Tr "new_org"}}</div>
<form class="ui form" action="{{.Link}}" method="post">
<input type="hidden" name="redirect_to" value="{{.CancelLink}}">
<div class="content">
{{template "base/alert" .}}
{{$createOrgCancelLink := .CancelLink}}
{{if not $createOrgCancelLink}}{{$createOrgCancelLink = .Req.RequestURI}}{{end}}
<div class="ui small modal" id="create-org-modal" data-cancel-link="{{$createOrgCancelLink}}">
<a class="inside close icon" role="button" tabindex="0" aria-label="{{ctx.Locale.Tr "close"}}">{{svg "octicon-x" 16}}</a>
<div class="header">{{ctx.Locale.Tr "new_org"}}</div>
<form class="ui form" action="{{AppSubUrl}}/org/create" method="post">
<input type="hidden" name="redirect_to" value="{{$createOrgCancelLink}}">
<div class="content">
{{template "base/alert" .}}
<div class="required field {{if .Err_OrgName}}error{{end}}">
<label for="org_name">{{ctx.Locale.Tr "org.org_name_holder"}}</label>
<input id="org_name" name="org_name" value="{{.org_name}}" autofocus required maxlength="40">
<span class="help">{{ctx.Locale.Tr "org.org_name_helper"}}</span>
</div>
<div class="required field {{if .Err_OrgName}}error{{end}}">
<label for="org_name">{{ctx.Locale.Tr "org.org_name_holder"}}</label>
<input id="org_name" name="org_name" value="{{.org_name}}" autofocus required maxlength="40">
<span class="help">{{ctx.Locale.Tr "org.org_name_helper"}}</span>
</div>
<div class="grouped required field {{if .Err_OrgVisibility}}error{{end}}">
<label>{{ctx.Locale.Tr "org.settings.visibility"}}</label>
<div class="field">
<div class="ui radio checkbox">
<input class="enable-system-radio" name="visibility" type="radio" value="0" {{if .visibility.IsPublic}}checked{{end}}>
<label>{{ctx.Locale.Tr "org.settings.visibility.public"}}</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input class="enable-system-radio" name="visibility" type="radio" value="1" {{if .visibility.IsLimited}}checked{{end}}>
<label>{{ctx.Locale.Tr "org.settings.visibility.limited"}}</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input class="enable-system-radio" name="visibility" type="radio" value="2" {{if .visibility.IsPrivate}}checked{{end}}>
<label>{{ctx.Locale.Tr "org.settings.visibility.private"}}</label>
</div>
</div>
</div>
<div class="field" id="permission_box">
<label>{{ctx.Locale.Tr "org.settings.permission"}}</label>
<div class="ui checkbox">
<input type="checkbox" name="repo_admin_change_team_access" {{if .repo_admin_change_team_access}}checked{{end}}>
<label>{{ctx.Locale.Tr "org.settings.repoadminchangeteam"}}</label>
</div>
</div>
<div class="grouped required field {{if .Err_OrgVisibility}}error{{end}}">
<label>{{ctx.Locale.Tr "org.settings.visibility"}}</label>
<div class="field">
<div class="ui radio checkbox">
<input id="create-org-visibility-public" class="enable-system-radio" name="visibility" type="radio" value="0" {{if .visibility.IsPublic}}checked{{end}}>
<label>{{ctx.Locale.Tr "org.settings.visibility.public"}}</label>
</div>
<div class="actions">
<a class="ui cancel button" href="{{.CancelLink}}">
{{svg "octicon-x"}} {{ctx.Locale.Tr "cancel"}}
</a>
<button class="ui primary button">
{{svg "octicon-check"}} {{ctx.Locale.Tr "org.create_org"}}
</button>
</div>
<div class="field">
<div class="ui radio checkbox">
<input id="create-org-visibility-limited" class="enable-system-radio" name="visibility" type="radio" value="1" {{if .visibility.IsLimited}}checked{{end}}>
<label>{{ctx.Locale.Tr "org.settings.visibility.limited"}}</label>
</div>
</form>
</div>
<div class="field">
<div class="ui radio checkbox">
<input id="create-org-visibility-private" class="enable-system-radio" name="visibility" type="radio" value="2" {{if .visibility.IsPrivate}}checked{{end}}>
<label>{{ctx.Locale.Tr "org.settings.visibility.private"}}</label>
</div>
</div>
</div>
<div class="field" id="permission_box">
<label>{{ctx.Locale.Tr "org.settings.permission"}}</label>
<div class="ui checkbox">
<input id="create-org-repo-admin-change-team-access" type="checkbox" name="repo_admin_change_team_access" {{if .repo_admin_change_team_access}}checked{{end}}>
<label>{{ctx.Locale.Tr "org.settings.repoadminchangeteam"}}</label>
</div>
</div>
</div>
</div>
<div class="actions">
<button type="button" class="ui cancel button">
{{svg "octicon-x"}} {{ctx.Locale.Tr "cancel"}}
</button>
<button class="ui primary button">
{{svg "octicon-check"}} {{ctx.Locale.Tr "org.create_org"}}
</button>
</div>
</form>
</div>
{{template "base/footer" .}}
+11 -1
View File
@@ -36,7 +36,17 @@
{{end}}
</div>
{{if .SignedUser.CanCreateOrganization}}
<a class="item" href="{{AppSubUrl}}/org/create">
<a
class="item show-modal"
href="{{AppSubUrl}}/org/create"
data-modal="#create-org-modal"
data-modal-org_name.value=""
data-modal-redirect_to.value="{{.Req.RequestURI}}"
data-modal-create-org-visibility-public.checked="true"
data-modal-create-org-visibility-limited.checked="false"
data-modal-create-org-visibility-private.checked="false"
data-modal-create-org-repo-admin-change-team-access.checked="true"
>
{{svg "octicon-plus" 16 "tw-ml-1 tw-mr-5"}}{{ctx.Locale.Tr "new_org"}}
</a>
{{end}}
+26 -1
View File
@@ -4,7 +4,17 @@
{{ctx.Locale.Tr "settings.orgs"}}
{{if .SignedUser.CanCreateOrganization}}
<div class="ui right">
<a class="ui primary tiny button" href="{{AppSubUrl}}/org/create">{{ctx.Locale.Tr "admin.orgs.new_orga"}}</a>
<a
class="ui primary tiny button show-modal"
href="{{AppSubUrl}}/org/create"
data-modal="#create-org-modal"
data-modal-org_name.value=""
data-modal-redirect_to.value="{{.Req.RequestURI}}"
data-modal-create-org-visibility-public.checked="true"
data-modal-create-org-visibility-limited.checked="false"
data-modal-create-org-visibility-private.checked="false"
data-modal-create-org-repo-admin-change-team-access.checked="true"
>{{ctx.Locale.Tr "admin.orgs.new_orga"}}</a>
</div>
{{end}}
</h4>
@@ -51,4 +61,19 @@
{{template "base/modal_actions_confirm" .}}
</div>
{{if .ShowCreateOrgModal}}
<script>
document.addEventListener('DOMContentLoaded', () => {
const modal = document.querySelector('#create-org-modal');
if (!modal) return;
window.$(modal).modal({
onHidden() {
const cancelLink = modal.getAttribute('data-cancel-link');
if (cancelLink) window.location.href = cancelLink;
},
}).modal('show');
});
</script>
{{end}}
{{template "user/settings/layout_footer" .}}
+1 -21
View File
@@ -70,27 +70,7 @@
background: var(--color-box-body) !important;
}
.page-content.organization.new.org .org-create-modal-wrap {
position: relative;
min-height: calc(100vh - 12rem);
padding: 2rem 0;
}
.page-content.organization.new.org .org-create-modal-wrap > .ui.modal.active {
position: relative;
top: auto;
left: auto;
margin: 0 auto;
}
.page-content.organization.new.org .org-create-modal-wrap .ui.modal .content .help {
#create-org-modal .content .help {
display: block;
margin-top: 0.5rem;
}
@media (max-width: 767.98px) {
.page-content.organization.new.org .org-create-modal-wrap {
min-height: auto;
padding: 1rem 0;
}
}
+14 -1
View File
@@ -125,6 +125,7 @@ export default defineComponent({
textOrgVisibilityLimited: '',
textOrgVisibilityPrivate: '',
subUrl: appSubUrl,
currentRequestURI: window.location.pathname + window.location.search,
...pageData.dashboardRepoList,
activeIndex: -1, // don't select anything at load, first cursor down will select
};
@@ -528,7 +529,19 @@ export default defineComponent({
{{ textMyOrgs }}
<span class="ui grey label tw-ml-2">{{ organizationsTotalCount }}</span>
</div>
<a class="tw-flex tw-items-center muted" v-if="canCreateOrganization" :href="subUrl + '/org/create'" :data-tooltip-content="textNewOrg">
<a
class="tw-flex tw-items-center muted show-modal"
v-if="canCreateOrganization"
:href="subUrl + '/org/create'"
:data-tooltip-content="textNewOrg"
data-modal="#create-org-modal"
data-modal-org_name.value=""
:data-modal-redirect_to.value="currentRequestURI"
data-modal-create-org-visibility-public.checked="true"
data-modal-create-org-visibility-limited.checked="false"
data-modal-create-org-visibility-private.checked="false"
data-modal-create-org-repo-admin-change-team-access.checked="true"
>
<svg-icon name="octicon-plus"/>
</a>
</h4>