|
17 | 17 | import PreviewPasswordControl from '../components/PreviewPasswordControl.svelte'; |
18 | 18 | import { getDisplayErrorMessage } from '../lib/errors.js'; |
19 | 19 | import { generatePreviewPassword } from '../lib/preview-password.js'; |
| 20 | + import { isGithubLinkedStatus } from '../lib/cloud-status.js'; |
20 | 21 |
|
21 | 22 | let { projectPath } = $props(); |
22 | 23 |
|
|
283 | 284 | } |
284 | 285 | cloudStatus = status; |
285 | 286 | // Detect GitHub-linked courses from the status response |
286 | | - const isGithub = status?.source?.type === 'github' || status?.source_type === 'github'; |
| 287 | + const isGithub = isGithubLinkedStatus(status); |
287 | 288 | if (project && project.githubLinked !== isGithub) { |
288 | 289 | project = { ...project, githubLinked: isGithub || undefined }; |
289 | 290 | } |
|
353 | 354 | } |
354 | 355 |
|
355 | 356 | function canPromoteToPreview(deployment) { |
356 | | - return deployment.id !== cloudStatus?.preview_deployment_id; |
| 357 | + return !project?.githubLinked && deployment.id !== cloudStatus?.preview_deployment_id; |
357 | 358 | } |
358 | 359 |
|
359 | 360 | function resetCloudLinkControls() { |
|
843 | 844 | } |
844 | 845 |
|
845 | 846 | async function confirmRepairDeploy() { |
| 847 | + if (project?.githubLinked) { |
| 848 | + await clearStaleBindingOnly(); |
| 849 | + return; |
| 850 | + } |
846 | 851 | staleBindingPrompt = null; |
847 | 852 | await deploy( |
848 | 853 | true, |
849 | | - project?.githubLinked ? { preview: true, promote: false } : { preview: getCloudPreviewState() === 'active' } |
| 854 | + { preview: getCloudPreviewState() === 'active' } |
850 | 855 | ); |
851 | 856 | resetDeployOptions(); |
852 | 857 | } |
|
1155 | 1160 | </div> |
1156 | 1161 | {/if} |
1157 | 1162 |
|
1158 | | - <div class="cloud-link-controls"> |
1159 | | - <label class="deploy-toggle-label"> |
1160 | | - <input type="checkbox" bind:checked={cloudLinkPasswordEditing} /> |
1161 | | - <span>{cloudStatus?.previewLink?.hasPassword ? 'Change password settings' : 'Require password'}</span> |
1162 | | - </label> |
1163 | | - {#if cloudLinkPasswordEditing} |
1164 | | - <PreviewPasswordControl |
1165 | | - id="cloud-panel-preview-password" |
1166 | | - bind:requirePassword={cloudLinkRequirePassword} |
1167 | | - bind:password={cloudLinkPassword} |
1168 | | - disabled={cloudActionBusy === 'preview-link'} |
1169 | | - /> |
1170 | | - {/if} |
1171 | | - <label class="cloud-select-label" for="cloud-link-expiry"> |
1172 | | - <span>Expiry</span> |
1173 | | - <select id="cloud-link-expiry" bind:value={cloudLinkExpiryAction} disabled={cloudActionBusy === 'preview-link'}> |
1174 | | - <option value="keep">Keep current expiry</option> |
1175 | | - <option value="extend7">Extend 7 days</option> |
1176 | | - </select> |
1177 | | - </label> |
1178 | | - </div> |
| 1163 | + {#if project?.githubLinked} |
| 1164 | + <p class="cloud-panel-note">Preview deploys, pointer updates, and preview-link changes are managed by GitHub for this course.</p> |
| 1165 | + {:else} |
| 1166 | + <div class="cloud-link-controls"> |
| 1167 | + <label class="deploy-toggle-label"> |
| 1168 | + <input type="checkbox" bind:checked={cloudLinkPasswordEditing} /> |
| 1169 | + <span>{cloudStatus?.previewLink?.hasPassword ? 'Change password settings' : 'Require password'}</span> |
| 1170 | + </label> |
| 1171 | + {#if cloudLinkPasswordEditing} |
| 1172 | + <PreviewPasswordControl |
| 1173 | + id="cloud-panel-preview-password" |
| 1174 | + bind:requirePassword={cloudLinkRequirePassword} |
| 1175 | + bind:password={cloudLinkPassword} |
| 1176 | + disabled={cloudActionBusy === 'preview-link'} |
| 1177 | + /> |
| 1178 | + {/if} |
| 1179 | + <label class="cloud-select-label" for="cloud-link-expiry"> |
| 1180 | + <span>Expiry</span> |
| 1181 | + <select id="cloud-link-expiry" bind:value={cloudLinkExpiryAction} disabled={cloudActionBusy === 'preview-link'}> |
| 1182 | + <option value="keep">Keep current expiry</option> |
| 1183 | + <option value="extend7">Extend 7 days</option> |
| 1184 | + </select> |
| 1185 | + </label> |
| 1186 | + </div> |
1179 | 1187 |
|
1180 | | - <div class="cloud-actions"> |
1181 | | - <button class="preview-link-btn" disabled={cloudActionBusy === 'preview-link'} onclick={saveCloudLinkSettings}> |
1182 | | - {cloudActionBusy === 'preview-link' ? 'Saving…' : cloudStatus?.previewLink?.exists ? 'Save Preview Link' : 'Create Preview Link'} |
1183 | | - </button> |
1184 | | - {#if getCloudPreviewState() === 'active'} |
1185 | | - <button class="preview-link-btn subtle" disabled={cloudActionBusy === 'preview-link'} onclick={disableCloudPreviewLink}>Turn Off</button> |
1186 | | - {/if} |
1187 | | - </div> |
| 1188 | + <div class="cloud-actions"> |
| 1189 | + <button class="preview-link-btn" disabled={cloudActionBusy === 'preview-link'} onclick={saveCloudLinkSettings}> |
| 1190 | + {cloudActionBusy === 'preview-link' ? 'Saving…' : cloudStatus?.previewLink?.exists ? 'Save Preview Link' : 'Create Preview Link'} |
| 1191 | + </button> |
| 1192 | + {#if getCloudPreviewState() === 'active'} |
| 1193 | + <button class="preview-link-btn subtle" disabled={cloudActionBusy === 'preview-link'} onclick={disableCloudPreviewLink}>Turn Off</button> |
| 1194 | + {/if} |
| 1195 | + </div> |
| 1196 | + {/if} |
1188 | 1197 | </section> |
1189 | 1198 |
|
1190 | 1199 | <section class="cloud-manage-section"> |
|
1251 | 1260 | <button |
1252 | 1261 | class="preview-link-btn subtle" |
1253 | 1262 | disabled={!canPromoteToPreview(deployment) || cloudActionBusy === `preview:${deployment.id}`} |
| 1263 | + title={project?.githubLinked ? 'Preview is managed by GitHub' : 'Set as Preview'} |
1254 | 1264 | onclick={() => promoteDeploymentPointer(deployment, 'preview')} |
1255 | 1265 | > |
1256 | 1266 | {cloudActionBusy === `preview:${deployment.id}` ? 'Setting…' : 'Set Preview'} |
|
1277 | 1287 | <div class="deploy-dialog-backdrop" role="presentation" onclick={() => deployPopoverOpen = false}> |
1278 | 1288 | {#if project?.githubLinked} |
1279 | 1289 | <div class="deploy-popover deploy-dialog-panel" role="dialog" aria-modal="true" aria-label="GitHub deploy info" tabindex="-1" onclick={(e) => e.stopPropagation()} onkeydown={(e) => e.stopPropagation()}> |
1280 | | - <p class="deploy-toggle-tip">Production deploys are managed by your GitHub repository. Push to deploy.</p> |
| 1290 | + <p class="deploy-toggle-tip">Deploys are managed by your GitHub repository. Push to deploy.</p> |
1281 | 1291 | <div class="preview-link-panel"> |
1282 | 1292 | <div class="preview-link-header"> |
1283 | 1293 | <span class="preview-link-title">Main Preview Link</span> |
|
1287 | 1297 | {#if getCloudPreviewState() === 'active'} |
1288 | 1298 | Stakeholders can open the main preview now. |
1289 | 1299 | {:else if getCloudPreviewState() === 'expired'} |
1290 | | - The main preview link expired. Turn it back on before sharing the Preview pointer. |
| 1300 | + The main preview link expired. |
1291 | 1301 | {:else if getCloudPreviewState() === 'disabled'} |
1292 | | - The main preview link is off. Turn it on to publish a preview URL. |
| 1302 | + The main preview link is off. |
1293 | 1303 | {:else} |
1294 | | - No main preview link exists yet. Turn it on to create one. |
| 1304 | + No main preview link exists yet. |
1295 | 1305 | {/if} |
1296 | 1306 | </p> |
1297 | 1307 | <div class="preview-link-actions"> |
1298 | | - <button class="preview-link-btn" disabled={isPreviewLinkBusy()} onclick={() => setPreviewLinkState(getCloudPreviewState() !== 'active', { autoSelectPreview: true })}> |
1299 | | - {#if isPreviewLinkBusy()} |
1300 | | - <div class="btn-spinner"></div> |
1301 | | - {:else if getCloudPreviewState() === 'active'} |
1302 | | - Turn Off Preview |
1303 | | - {:else} |
1304 | | - Turn On Preview |
1305 | | - {/if} |
1306 | | - </button> |
1307 | 1308 | {#if getCloudPreviewState() === 'active'} |
1308 | 1309 | <button class="preview-link-btn subtle" onclick={openCloudPreview}>Open Link</button> |
1309 | 1310 | {/if} |
1310 | 1311 | </div> |
1311 | | - {#if getCloudPreviewState() !== 'active' && previewLinkNeedsPassword()} |
1312 | | - <PreviewPasswordControl |
1313 | | - id="project-github-preview-password" |
1314 | | - bind:requirePassword={previewRequirePassword} |
1315 | | - bind:password={previewPassword} |
1316 | | - disabled={isPreviewLinkBusy()} |
1317 | | - /> |
1318 | | - {/if} |
1319 | 1312 | </div> |
1320 | | - <p class="deploy-toggle-tip">You can still update the Preview pointer directly from Desktop.</p> |
| 1313 | + <p class="deploy-toggle-tip">Preview deploys and pointer updates are managed by GitHub.</p> |
1321 | 1314 | <div class="deploy-popover-actions"> |
1322 | 1315 | <button class="deploy-popover-cancel" onclick={() => deployPopoverOpen = false}>Dismiss</button> |
1323 | | - <button class="deploy-popover-confirm" disabled={!canUpdatePreviewPointer() || isPreviewLinkBusy()} onclick={() => deploy(false, { preview: true, promote: false })}>Deploy Preview</button> |
1324 | 1316 | </div> |
1325 | 1317 | </div> |
1326 | 1318 | {:else} |
|
1529 | 1521 | title="Linked Cloud Course Missing" |
1530 | 1522 | message={staleBindingPrompt.message || `"${project?.title || project?.name || 'This project'}" is still linked to a CourseCode Cloud course that no longer exists.`} |
1531 | 1523 | detail={project?.githubLinked |
1532 | | - ? 'You can clear the old local cloud link and update the preview deployment now, or clear the link only and leave this project in a not deployed state. Production deploys stay managed by GitHub.' |
| 1524 | + ? 'You can clear the old local cloud link and leave this project in a not deployed state. GitHub-linked deploys stay managed by GitHub.' |
1533 | 1525 | : 'You can clear the old local cloud link and redeploy now, or clear the link only and leave this project in a not deployed state.'} |
1534 | | - alternateLabel="Clear Link Only" |
1535 | | - confirmLabel={project?.githubLinked ? 'Clear Link and Deploy Preview' : 'Clear Link and Redeploy'} |
| 1526 | + alternateLabel={project?.githubLinked ? undefined : 'Clear Link Only'} |
| 1527 | + confirmLabel={project?.githubLinked ? 'Clear Link' : 'Clear Link and Redeploy'} |
1536 | 1528 | cancelLabel="Not Now" |
1537 | 1529 | onconfirm={confirmRepairDeploy} |
1538 | 1530 | onalternate={clearStaleBindingOnly} |
|
2159 | 2151 | background: var(--bg-primary); |
2160 | 2152 | } |
2161 | 2153 |
|
| 2154 | + .cloud-panel-note { |
| 2155 | + margin: 12px 0 0; |
| 2156 | + color: var(--text-secondary); |
| 2157 | + font-size: 12px; |
| 2158 | + line-height: 1.45; |
| 2159 | + } |
| 2160 | +
|
2162 | 2161 | .cloud-label, |
2163 | 2162 | .cloud-select-label span, |
2164 | 2163 | .cloud-reason-field span { |
|
0 commit comments