@@ -4,17 +4,21 @@
4 4 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
{% block content %}
5 5 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<h1 class="text-2xl font-bold text-gray-100 mb-2">{{ project.name }}</h1>
6 6 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
{% include "fossil/_project_nav.html" %}
7 7 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
8 8 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<div class="max-w-2xl">
9 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <h2 class="text-lg font-semibold text-gray-200 mb-4">Repository Sync</h2>
10 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
9 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% if sync_configured %}
10 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <!-- Sync is configured — show status and pull button -->
11 11 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<div class="rounded-lg bg-gray-800 border border-gray-700 p-5 mb-6">
12 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <div class="flex items-center justify-between mb-4">
13 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <h2 class="text-lg font-semibold text-gray-200">Upstream Sync</h2>
14 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <span class="inline-flex rounded-full bg-green-900/50 px-2 py-0.5 text-xs font-semibold text-green-300">Configured</span>
15 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </div>
12 16 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<dl class="space-y-3">
13 17 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<div class="flex items-center justify-between">
14 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <dt class="text-sm text-gray-400">Remote</dt>
15 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <dd class="text-sm text-gray-200 font-mono">{{ remote_url|default:"No remote configured" }}</dd>
18 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <dt class="text-sm text-gray-400">Remote URL</dt>
19 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <dd class="text-sm text-gray-200 font-mono truncate max-w-xs">{{ fossil_repo.remote_url }}</dd>
16 20 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</div>
17 21 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<div class="flex items-center justify-between">
18 22 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<dt class="text-sm text-gray-400">Last synced</dt>
19 23 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<dd class="text-sm text-gray-200">{% if fossil_repo.last_sync_at %}{{ fossil_repo.last_sync_at|timesince }} ago{% else %}Never{% endif %}</dd>
20 24 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</div>
@@ -25,41 +29,88 @@
25 29 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<div class="flex items-center justify-between">
26 30 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<dt class="text-sm text-gray-400">Repository size</dt>
27 31 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<dd class="text-sm text-gray-200">{{ fossil_repo.file_size_bytes|filesizeformat }}</dd>
28 32 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</div>
29 33 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</dl>
30 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- </div>
31 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
32 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- {% if remote_url %}
33 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <form method="post">
34 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- {% csrf_token %}
35 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <button type="submit" class="inline-flex items-center gap-2 rounded-md bg-brand px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-brand-hover">
36 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
37 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182" />
38 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- </svg>
39 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Pull from Upstream
40 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- </button>
41 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- </form>
42 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- {% else %}
43 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <p class="text-sm text-gray-500">No remote URL configured. This repository was created locally.</p>
44 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- {% endif %}
34 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
35 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <div class="mt-5 flex items-center gap-3">
36 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <form method="post">
37 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% csrf_token %}
38 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <input type="hidden" name="action" value="pull">
39 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <button type="submit" class="inline-flex items-center gap-2 rounded-md bg-brand px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-brand-hover">
40 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
41 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182" />
42 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </svg>
43 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Pull from Upstream
44 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </button>
45 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </form>
46 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <form method="post">
47 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% csrf_token %}
48 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <input type="hidden" name="action" value="disable">
49 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <button type="submit" class="rounded-md bg-gray-700 px-3 py-2 text-sm text-gray-400 hover:text-white ring-1 ring-inset ring-gray-600 hover:bg-gray-600">
50 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Disable Sync
51 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </button>
52 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </form>
53 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </div>
54 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </div>
45 55 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
46 56 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
{% if result %}
47 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <div class="mt-4 rounded-lg {% if result.success %}bg-green-900/30 border border-green-800{% else %}bg-red-900/30 border border-red-800{% endif %} p-4">
57 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <div class="rounded-lg {% if result.success %}bg-green-900/20 border border-green-800{% else %}bg-red-900/20 border border-red-800{% endif %} p-4">
48 58 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<div class="text-sm {% if result.success %}text-green-300{% else %}text-red-300{% endif %}">
49 59 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
{% if result.success %}
50 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- {% if result.artifacts_received > 0 %}
51 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Pulled {{ result.artifacts_received }} new artifacts.
52 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- {% else %}
53 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Already up to date.
54 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- {% endif %}
60 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% if result.artifacts_received > 0 %}Pulled {{ result.artifacts_received }} new artifacts.{% else %}Already up to date.{% endif %}
55 61 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
{% else %}
56 62 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Sync failed: {{ result.message }}
57 63 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
{% endif %}
58 64 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</div>
59 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- {% if result.message %}
60 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <pre class="mt-2 text-xs text-gray-500 font-mono">{{ result.message }}</pre>
61 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- {% endif %}
65 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% if result.message %}<pre class="mt-2 text-xs text-gray-500 font-mono">{{ result.message }}</pre>{% endif %}
66 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </div>
67 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% endif %}
68 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
69 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% else %}
70 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <!-- Sync not configured — show setup wizard -->
71 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <div class="rounded-lg bg-gray-800 border border-gray-700 p-6">
72 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <div class="text-center mb-6">
73 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <svg class="mx-auto h-12 w-12 text-gray-600" fill="none" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor">
74 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182" />
75 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </svg>
76 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <h2 class="mt-3 text-lg font-semibold text-gray-200">Configure Upstream Sync</h2>
77 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <p class="mt-1 text-sm text-gray-400">Connect this repository to an upstream Fossil server to pull updates automatically.</p>
78 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </div>
79 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
80 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <form method="post" class="space-y-4">
81 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% csrf_token %}
82 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <input type="hidden" name="action" value="configure">
83 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
84 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <div>
85 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <label class="block text-sm font-medium text-gray-300 mb-1">Remote URL</label>
86 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <input type="url" name="remote_url" required
87 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ value="{{ detected_remote }}"
88 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ placeholder="https://fossil-scm.org/home"
89 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class="w-full rounded-md border-gray-700 bg-gray-900 text-gray-100 shadow-sm focus:border-brand focus:ring-brand sm:text-sm px-3 py-2 font-mono">
90 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% if detected_remote %}
91 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <p class="mt-1 text-xs text-green-400">Auto-detected from repository: {{ detected_remote }}</p>
92 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% else %}
93 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <p class="mt-1 text-xs text-gray-500">Enter the URL of the upstream Fossil server (e.g. https://fossil-scm.org/home)</p>
94 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {% endif %}
95 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </div>
96 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
97 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <div class="bg-gray-900/50 rounded-md p-4 text-sm text-gray-400">
98 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <h4 class="font-medium text-gray-300 mb-2">What sync does:</h4>
99 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <ul class="space-y-1 text-xs">
100 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <li>Pulls new checkins, wiki pages, tickets, and forum posts from the remote</li>
101 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <li>Runs automatically every 15 minutes via background task</li>
102 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <li>You can also pull manually at any time</li>
103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <li>Your local data is never overwritten — only new artifacts are added</li>
104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </ul>
105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </div>
106 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
107 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <div class="flex justify-end">
108 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <button type="submit" class="rounded-md bg-brand px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-brand-hover">
109 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Enable Sync
110 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </button>
111 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </div>
112 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </form>
62 113 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</div>
63 114 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
{% endif %}
64 115 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</div>
65 116 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
{% endblock %}
66 117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!