Files
RoleForge/app/templates/role-create.xhtml
Sergey Antropoff 01d598eea5 - Админка: настройка pull-реестра (Hub / Harbor / Nexus) в БД, шифрование секретов;
обновлён /admin/config и API для os_registry.
- Molecule/раннер: env из конфигурации, ensure roleforge-os (ensure_roleforge_os.yml),
  os_registry_pull и доработки executors / runner / create.yml.
- /admin/os-images: выбор реестра, buildx (в т.ч. split amd64+arm64 + imagetools),
  опция --no-cache, стрим логов; domain.py: план команд build, ретраи push.
- UI: брендинг (app_name, app_tagline) из app_config через get_ui_branding_context;
  base.xhtml, role-create / role-view, core.js, pages-main, стили.
- Dockerfiles: требование Python ≥3.9 (assert), доработки alt9/astra/debian9/ubuntu20
  и др.; новые Dockerfile.arm64 для centos7/centos8.
- Конфиг: .env.example, config.py, pyproject.toml.
2026-05-06 07:52:29 +03:00

139 lines
8.1 KiB
HTML

{% extends "base.xhtml" %}
{% from "macros/page-hero.xhtml" import page_hero %}
{% block content %}
<div class="dashboard-page roles-page" data-role-create="true">
{{ page_hero("Library", "Create Role", "Fill in details and build the file catalog; Create saves the role and opens Role details.") }}
<section class="dashboard-panel dashboard-panel--primary role-view-tabbed-shell">
<div class="role-view-tabs" role="tablist" aria-label="Role sections">
<button type="button" class="role-view-tab" role="tab" id="role-tab-trigger-details" aria-selected="true" aria-controls="role-tab-panel-details">Role details</button>
<button type="button" class="role-view-tab" role="tab" id="role-tab-trigger-catalog" aria-selected="false" aria-controls="role-tab-panel-catalog" tabindex="-1">Role files catalog</button>
</div>
<div class="role-view-tabbed-panels">
<section id="role-tab-panel-details" class="role-view-tab-panel" role="tabpanel" aria-labelledby="role-tab-trigger-details">
<div class="dashboard-panel-h">
<div>
<h2 class="dashboard-panel-title">Role details</h2>
<p class="dashboard-panel-sub">Name, category, source and description — same layout as on Role Details.</p>
</div>
</div>
<form id="role-view-form" class="roles-form-grid">
<label class="schema-field">
<span class="schema-field__label">Role Name</span>
<input type="text" id="role-view-name" required="required" placeholder="nginx_setup" />
</label>
<label class="schema-field">
<span class="schema-field__label">Category</span>
<select id="role-view-category">
<option value="">Uncategorized</option>
</select>
</label>
<label class="schema-field">
<span class="schema-field__label">Source Type</span>
<select id="role-view-source-type">
<option value="inline">inline</option>
<option value="git">git</option>
<option value="galaxy">galaxy</option>
</select>
</label>
<label class="schema-field">
<span class="schema-field__label">Source Ref</span>
<input type="text" id="role-view-source-ref" placeholder="repository or role reference" />
</label>
<label class="schema-field schema-field--wide">
<span class="schema-field__label">Description</span>
<textarea id="role-view-description" rows="5" placeholder="Describe what this role does…"></textarea>
</label>
<label class="schema-field schema-field--wide">
<span class="schema-field__label">Tags</span>
<input type="text" id="role-view-tags" placeholder="e.g. nginx, ssl, web — comma-separated" autocomplete="off" />
</label>
<div class="schema-field schema-field--wide" id="role-os-families-wrap">
<span class="schema-field__label">Target OS families</span>
<div class="role-os-family-grid" id="role-os-family-grid" aria-label="Target operating system families"></div>
<p class="muted small-note" style="margin:6px 0 0">Optional. Shown as badges in the role catalog; pick all that apply.</p>
</div>
<div class="schema-field schema-field--wide role-visibility-field">
<span class="schema-field__label" id="role-visibility-label">Who can see this role</span>
<div class="radio-segment-group role-visibility-segments" role="radiogroup" aria-labelledby="role-visibility-label">
<label class="radio-segment">
<input type="radio" name="role-view-visibility" value="public" />
<span class="radio-segment-face">
<span class="radio-segment-title radio-segment-title--with-icon">
<i class="fa-solid fa-globe radio-segment-icon" aria-hidden="true"></i>
<span>Public</span>
</span>
<span class="radio-segment-desc">Listed for everyone; anyone can browse or fork.</span>
</span>
</label>
<label class="radio-segment">
<input type="radio" name="role-view-visibility" value="team" />
<span class="radio-segment-face">
<span class="radio-segment-title radio-segment-title--with-icon">
<i class="fa-solid fa-users radio-segment-icon" aria-hidden="true"></i>
<span>Team</span>
</span>
<span class="radio-segment-desc">Visible to members of the team you choose.</span>
</span>
</label>
<label class="radio-segment">
<input type="radio" name="role-view-visibility" value="personal" checked="checked" />
<span class="radio-segment-face">
<span class="radio-segment-title radio-segment-title--with-icon">
<i class="fa-solid fa-user-shield radio-segment-icon" aria-hidden="true"></i>
<span>Personal</span>
</span>
<span class="radio-segment-desc">Only you — not listed in the public library.</span>
</span>
</label>
</div>
<p class="muted small-note role-visibility-footnote">New roles are personal. After editing, open the role and use Publish to add it to the public library.</p>
</div>
<div class="schema-field schema-field--wide role-team-picker-field" id="role-team-picker-wrap" hidden="hidden">
<span class="schema-field__label">Team</span>
<div class="role-team-picker-actions">
<span id="role-team-display" class="role-team-display role-team-display--summary muted"></span>
<button type="button" class="cta-button role-team-picker-open-btn" id="role-team-choose-btn">
Choose team…
</button>
</div>
<p class="muted small-note" style="margin: 10px 0 0">Only teams you belong to (active membership) are listed.</p>
</div>
</form>
</section>
<section id="role-tab-panel-catalog" class="dashboard-panel role-view-tab-panel" role="tabpanel" aria-labelledby="role-tab-trigger-catalog" hidden="hidden">
<div class="dashboard-panel-h">
<div>
<h2 class="dashboard-panel-title">Role files catalog</h2>
<p class="dashboard-panel-sub">Folders mirror Ansible layout. Open files from the tree; use icons to add a folder or file.</p>
</div>
<div class="role-file-catalog-toolbar">
<button type="button" class="btn-icon btn-icon--add" id="role-view-add-folder-btn" data-tooltip="Add folder" aria-label="Add folder">
<i class="fa-solid fa-folder-plus" aria-hidden="true"></i>
</button>
<button type="button" class="btn-icon btn-icon--export" id="role-view-add-file-btn" data-tooltip="Add file" aria-label="Add file">
<i class="fa-solid fa-file-circle-plus" aria-hidden="true"></i>
</button>
<button type="button" class="btn-icon btn-icon--open" id="role-view-files-upload-btn" data-tooltip="Upload files into files/" aria-label="Upload files into files directory">
<i class="fa-solid fa-upload" aria-hidden="true"></i>
</button>
</div>
</div>
<div id="role-view-catalog" class="role-file-catalog" aria-label="Role files tree"></div>
</section>
</div>
</section>
<div class="roles-page-bottom-actions">
<button type="submit" form="role-view-form" class="cta-button">Create</button>
<button type="button" class="btn-muted" id="role-view-test-btn">Test</button>
</div>
</div>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/theme/dracula.min.css" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/yaml/yaml.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/javascript/javascript.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/edit/matchbrackets.min.js"></script>
{% endblock %}