Improve UI for App Deployment Options in Dev Center (#2266)
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test-backend (24.x) (push) Has been cancelled
test / API tests (node env, api-test) (24.x) (push) Has been cancelled
test / puterjs (node env, vitest) (24.x) (push) Has been cancelled

* Improve UI for App Deployment Options in Dev Center

- Added CSS styling for deployment option cards
- Implemented active state switching between deployment methods with guardrails
- Abstracted saveEditApp for reuse across Deploy and Edit tabs
- Added error handling for invalid URLs in the Deploy tab

* updated mode's description and fixed function's error

* updated by npm install

* Revert "updated by npm install"

This reverts commit 82cd962f62.

* in url mode the deploy button is enabled by default
This commit is contained in:
Sauhbagya Prasad
2026-01-14 00:24:08 +05:30
committed by GitHub
parent 07f3387363
commit 529a3d026b
2 changed files with 131 additions and 13 deletions
+34 -1
View File
@@ -363,7 +363,7 @@ label {
#edit-app{
display: none;
}
#create-app-error, #edit-app-error, #jip-error {
#create-app-error,#deploy-app-error, #edit-app-error, #jip-error {
display: none;
}
@@ -1468,3 +1468,36 @@ dialog{
.tab-btn-separator{
display: none;
}
.deploy-app-card-container {
max-width: 100%;
margin: auto;
}
.deploy-app-card {
background: #fff;
border: 1.5px solid #dbe3f0;
border-radius: 14px;
padding: 20px;
margin-bottom: 24px;
transition: border-color 0.2s ease;
}
.deploy-app-card.deploy-app-active {
border-color: #3a85ff;
}
.deploy-app-card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.deploy-app-card-or {
text-align: center;
margin: 10px 0 20px;
color: #9ca3af;
font-weight: 500;
}
+97 -12
View File
@@ -277,7 +277,12 @@ async function create_app (title, source_path = null, items = null) {
}
$(document).on('click', '.deploy-btn', function (e) {
deploy(currently_editing_app, dropped_items);
const $activeCard = $('.deploy-app-card.deploy-app-active');
if ( $activeCard.hasClass('deploy-app-card-files') ) {
deploy(currently_editing_app, dropped_items);
} else if ( $activeCard.hasClass('deploy-app-card-link') ) {
saveEditedApp('deploy-app-index-url');
}
});
$(document).on('click', '.edit-app, .go-to-edit-app', function (e) {
@@ -288,6 +293,32 @@ $(document).on('click', '.edit-app, .go-to-edit-app', function (e) {
$(document).on('click', '.delete-app', async function (e) {
});
$(document).on('click', '.deploy-app-card', function () {
if ( $(this).hasClass('deploy-app-active') ) {
return;
}
$('.deploy-btn').addClass('disabled');
if ( $(this).hasClass('deploy-app-card-files') ) {
$('#deploy-app-index-url').val('');
}
if ( $(this).hasClass('deploy-app-card-link') ) {
reset_drop_area();
if ( $('#deploy-app-index-url').val() != '' ) {
$('.deploy-btn').removeClass('disabled');
}
}
$('.deploy-app-card').removeClass('deploy-app-active');
$(this)
.addClass('deploy-app-active')
.find('input[type="radio"]')
.prop('checked', true);
});
$(document).on('input change', '#deploy-app-index-url', () => {
$('.deploy-btn').removeClass('disabled');
});
// generate app link
function applink (app) {
return `${protocol}://${domain}${port ? `:${port}` : ''}/app/${app.name}`;
@@ -349,12 +380,40 @@ function generate_edit_app_section (app) {
</ul>
<div class="section-tab active" data-tab="deploy">
<div class="error" id="deploy-app-error" style="margin-bottom: 25px;"></div>
<div class="success deploy-success-msg">
New version deployed successfully 🎉<span class="close-success-msg">&times;</span>
<p style="margin-bottom:0;"><span class="open-app button button-action" data-uid="${html_encode(app.uid)}" data-app-name="${html_encode(app.name)}">Give it a try!</span></p>
</div>
<div class="drop-area disable-user-select">${drop_area_placeholder}</div>
<button class="deploy-btn disable-user-select button button-primary disabled">Deploy Now</button>
<div class="deploy-app-card-container">
<!-- FILE MODE -->
<div class="deploy-app-card deploy-app-card-files deploy-app-active" >
<div class="deploy-app-card-header">
<div>
<h3>Use files</h3>
<p>Upload and deploy static assets like HTML, CSS, and JavaScript directly to host your app.</p>
</div>
<input type="radio" name="deploy-app-card-mode" checked />
</div>
<div class="drop-area disable-user-select">${drop_area_placeholder}</div>
</div>
<div class="deploy-app-card-or">OR</div>
<!-- LINK MODE -->
<div class="deploy-app-card deploy-app-card-link" >
<div class="deploy-app-card-header">
<div>
<h3>Use link</h3>
<p>Set the apps index to any publicly accessible URL where your app is already deployed.</p>
</div>
<input type="radio" name="deploy-app-card-mode" />
</div>
<input type="text" id="deploy-app-index-url" placeholder="Add your link" value="${html_encode(app.index_url)}" />
</div>
<button class="deploy-btn disable-user-select button button-primary disabled">Deploy Now</button>
</div>
</div>
<div class="section-tab" data-tab="info">
@@ -1047,9 +1106,19 @@ async function edit_app_section (cur_app_name, tab = 'deploy') {
}
$(document).on('click', '.edit-app-save-btn', async function (e) {
e.preventDefault();
saveEditedApp('edit-app-index-url');
});
async function saveEditedApp (mode) {
const title = $('#edit-app-title').val();
const name = $('#edit-app-name').val();
const index_url = $('#edit-app-index-url').val();
var index_url;
if ( mode == 'edit-app-index-url' ) {
index_url = $('#edit-app-index-url').val();
} else {
index_url = $('#deploy-app-index-url').val();
}
const description = $('#edit-app-description').val();
const uid = $('#edit-app-uid').val();
const height = $('#edit-app-window-height').val();
@@ -1179,8 +1248,13 @@ $(document).on('click', '.edit-app-save-btn', async function (e) {
// error?
if ( error ) {
$('#edit-app-error').show();
$('#edit-app-error').html(error);
if ( mode == 'edit-app-index-url' ) {
$('#edit-app-error').show();
$('#edit-app-error').html(error);
} else {
$('#deploy-app-error').show();
$('#deploy-app-error').html(error);
}
document.body.scrollTop = document.documentElement.scrollTop = 0;
return;
}
@@ -1236,8 +1310,13 @@ $(document).on('click', '.edit-app-save-btn', async function (e) {
trackOriginalValues(); // Update original values after save
toggleSaveButton(); //Disable Save Button after succesful save
toggleResetButton(); //DIsable Reset Button after succesful save
$('#edit-app-error').hide();
$('#edit-app-success').show();
if ( mode == 'edit-app-index-url' ) {
$('#edit-app-error').hide();
$('#edit-app-success').show();
} else {
$('#deploy-app-error').hide();
$('.deploy-success-msg').show();
}
document.body.scrollTop = document.documentElement.scrollTop = 0;
// Update open-app-btn
$(`.open-app-btn[data-app-uid="${uid}"]`).attr('data-app-name', app.name);
@@ -1252,9 +1331,15 @@ $(document).on('click', '.edit-app-save-btn', async function (e) {
$(`[data-app-uid="${uid}"]`).attr('data-app-title', html_encode(app.title));
$(`[data-app-name="${uid}"]`).attr('data-app-name', html_encode(app.name));
}).catch((err) => {
$('#edit-app-success').hide();
$('#edit-app-error').show();
$('#edit-app-error').html(err.error?.message);
if ( mode == 'edit-app-index-url' ) {
$('#edit-app-success').hide();
$('#edit-app-error').show();
$('#edit-app-error').html(err.error?.message);
} else {
$('.deploy-success-msg').hide();
$('#deploy-app-error').show();
$('#deploy-app-error').html(err.error?.message);
}
// scroll to top so that user sees error message
document.body.scrollTop = document.documentElement.scrollTop = 0;
// re-enable submit button
@@ -1262,7 +1347,7 @@ $(document).on('click', '.edit-app-save-btn', async function (e) {
}).finally(() => {
puter.ui.hideSpinner();
});
});
};
$(document).on('input change', '#edit-app input, #edit-app textarea, #edit-app select', () => {
toggleSaveButton();