Modified - Converted the organization creation page to a modal-style dialog and preserved the caller page for cancel.
This commit is contained in:
+7
-1
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -1 +1 @@
|
||||
aab373ab6d6705fd6044ef30ecba0d9a07c58f1f
|
||||
e3591b59f1c56991f10b6f23203f3c9965823eee
|
||||
|
||||
+42
-2
@@ -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
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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" .}}
|
||||
|
||||
@@ -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
@@ -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" .}}
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user