Skip to content

Commit 52fb97f

Browse files
alexlave100Ubuntu
andauthored
[Azure:CosmosDB] - azlocal -> az and other sample fixes (#67)
* . * . * . * . * . --------- Co-authored-by: Ubuntu <azureuser@Azure-dev-amd64.q53sj25ltxcete14z4piy1ufza.gvxx.internal.cloudapp.net>
1 parent 96d1cfa commit 52fb97f

6 files changed

Lines changed: 40 additions & 117 deletions

File tree

samples/web-app-cosmosdb-nosql-api/python/scripts/...

Whitespace-only changes.

samples/web-app-cosmosdb-nosql-api/python/scripts/deploy.sh

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,7 @@ RANDOM_SUFFIX=$(echo $RANDOM)
1515
NEW_DB_NAME="vacationplanner_${RANDOM_SUFFIX}"
1616
AZURECOSMOSDB_DATABASENAME=$NEW_DB_NAME
1717
AZURECOSMOSDB_CONTAINERNAME="activities_${RANDOM_SUFFIX}"
18-
AURECOSMOSDB_PARTITION_KEY="/partitionKey"
19-
20-
# Start azure CLI local mode session
21-
az login
22-
23-
# Change the current directory to the script's directory
24-
#cd "$CURRENT_DIR" || exit
18+
AURECOSMOSDB_PARTITION_KEY="/username"
2519

2620
# Validates if the resource group exists in the subscription, if not creates it
2721
echo "Checking if resource group [$RESOURCE_GROUP_NAME] exists..."
@@ -118,14 +112,13 @@ zip -r "$ZIPFILE" app.py cosmosdb_client.py static templates requirements.txt
118112

119113
# Deploy the web app
120114
echo "Deploying web app [$WEB_APP_NAME] with zip file [$ZIPFILE]..."
115+
echo "Using az webapp deploy command for LocalStack emulator environment."
121116
az webapp deploy \
122117
--resource-group $RESOURCE_GROUP_NAME \
123118
--name $WEB_APP_NAME \
124119
--src-path ${ZIPFILE} \
125120
--type zip \
126-
--async true \
127-
--debug \
128-
--verbose 1>/dev/null
121+
--async true
129122

130123
# Remove the zip package of the web app
131124
if [ -f "$ZIPFILE" ]; then

samples/web-app-cosmosdb-nosql-api/python/scripts/validate.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#!/bin/bash
22

3-
# Variables
43
# Check resource group
54
az group show \
65
--name local-rg \

samples/web-app-cosmosdb-nosql-api/python/src/app.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,5 @@ def delete(activity_id: str):
110110

111111
return redirect(url_for('index'))
112112

113-
@app.route('/edit/<string:activity_id>', methods=['POST'])
114-
def edit(activity_id: str):
115-
new_text = request.form.get('new_text')
116-
117-
if new_text:
118-
logger.info(f"Updating ID {activity_id} with activity: {new_text}")
119-
get_cosmos().update_document_activity(activity_id, username, new_text)
120-
121-
return redirect(url_for('index'))
122-
123113
if __name__ == '__main__':
124114
app.run(debug=True)

samples/web-app-cosmosdb-nosql-api/python/src/cosmosdb_client.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,16 @@ def update_document_activity(self, activity_id: str, username: str, new_text: st
6262
logger.warning(f"Update failed: {e}")
6363

6464
def delete_document_by_id(self, doc_id: str, username: str):
65+
self.ensure_initialized()
66+
6567
try:
66-
self.container.delete_item(item=doc_id, partition_key=username)
67-
except exceptions.CosmosResourceNotFoundError:
68-
pass
68+
doc_to_delete = self.container.read_item(item=doc_id, partition_key=[username])
69+
self.container.delete_item(item=doc_to_delete, partition_key=[username])
70+
except exceptions.CosmosResourceNotFoundError as e:
71+
logger.warning(f"Cosmos resource with doc_id {doc_id} and username {username} was not found")
72+
raise e
73+
except exceptions.CosmosHttpResponseError as e:
74+
raise e
75+
except Exception as e:
76+
logger.info(f"DELETE METHOD CRASHED: Error Type: {type(e).__name__}, Message: {e}")
77+
raise e
Lines changed: 25 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,3 @@
1-
<!--- <!DOCTYPE html>
2-
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8">
5-
<title>Vacation Planner</title>
6-
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/css/bootstrap.min.css') }}">
7-
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
8-
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
9-
</head>
10-
<body style="background: linear-gradient(135deg, #fff 0%, #a2d4f7 100%); min-height: 100vh;">
11-
<div class="container py-4 my-5 bg-white bg-opacity-75 rounded-4 shadow-lg" style="max-width:480px;">
12-
<img src="{{ url_for('static', filename='summer_banner.jpg') }}" alt="Summer Banner" class="img-fluid rounded mb-3 w-100" style="max-height:180px; object-fit:cover;">
13-
<h1 class="display-9 fw-bold sea-title mb-4">Vacation Planner</h1>
14-
<form method="post" class="sea-form mb-4" style="max-width: 520px; margin: 0 auto;">
15-
<div style="display: flex; width: 100%;">
16-
<input type="text" name="activity" class="form-control sea-input" placeholder="Enter a vacation activity..." required>
17-
<button type="submit" class="sea-btn">Add</button>
18-
</div>
19-
</form>
20-
<div class="table-responsive" style="width: 100%;">
21-
<table class="table sea-table align-middle" style="width: 100%; margin: 0;">
22-
<thead>
23-
<tr>
24-
<th class="text-start">Activity</th>
25-
<th class="text-start align-middle action-col" style="width: 90px;">Action</th>
26-
</tr>
27-
</thead>
28-
<tbody>
29-
{% for activity in activities %}
30-
<tr>
31-
<td class="text-start">{{ activity[1] }}</td>
32-
<td class="text-start align-middle action-col" style="width: 90px;">
33-
<form method="post" action="{{ url_for('delete', activity_id=activity[0]) }}" class="d-inline">
34-
<input type="hidden" name="row_id" value="{{ activity[0] }}">
35-
<button type="submit" class="sea-btn" style="width: 90px;">Delete</button>
36-
</form>
37-
</td>
38-
</tr>
39-
{% else %}
40-
<tr>
41-
<td colspan="2" class="text-center text-muted fst-italic">No vacation plans yet!</td>
42-
</tr>
43-
{% endfor %}
44-
</tbody>
45-
</table>
46-
</div>
47-
</div>
48-
</body>
49-
</html> --->
50-
51-
521
<!DOCTYPE html>
532
<html lang="en">
543
<head>
@@ -59,15 +8,17 @@ <h1 class="display-9 fw-bold sea-title mb-4">Vacation Planner</h1>
598
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
609
</head>
6110
<body style="background: linear-gradient(135deg, #fff 0%, #a2d4f7 100%); min-height: 100vh;">
62-
<div class="container py-4 my-5 bg-white bg-opacity-75 rounded-4 shadow-lg" style="max-width:520px;">
11+
<div class="container py-4 my-5 bg-white bg-opacity-75 rounded-4 shadow-lg" style="max-width:600px;">
6312
<img src="{{ url_for('static', filename='summer_banner.jpg') }}" alt="Summer Banner" class="img-fluid rounded mb-3 w-100" style="max-height:180px; object-fit:cover;">
6413

6514
<h1 class="display-9 fw-bold sea-title mb-4 text-center">Vacation Planner</h1>
6615

67-
<form method="post" class="sea-form mb-4">
68-
<div class="d-flex w-100">
69-
<input type="text" name="activity" class="form-control sea-input" placeholder="Enter a vacation activity..." required>
70-
<button type="submit" class="sea-btn ms-2">Add</button>
16+
<form method="post" action="{{ url_for('index') }}" class="sea-form mb-4" style="max-width: 600px; margin: 0 auto;">
17+
<div style="display: flex; width: 100%;">
18+
<input type="hidden" name="row_id" value="{{ edit_id or '' }}">
19+
<input id="activityInput" type="text" name="activity" class="form-control sea-input"
20+
placeholder="Enter a vacation activity..." value="{{ edit_activity or '' }}" required autofocus>
21+
<button type="submit" class="sea-btn ms-2">{{ 'Update' if edit_id else 'Add' }}</button>
7122
</div>
7223
</form>
7324

@@ -76,36 +27,23 @@ <h1 class="display-9 fw-bold sea-title mb-4 text-center">Vacation Planner</h1>
7627
<thead>
7728
<tr>
7829
<th class="text-start">Activity</th>
79-
<th class="text-end" style="width: 160px;">Actions</th>
30+
<th class="text-center align-middle" style="width: 220px;" colspan="2">Action</th>
8031
</tr>
8132
</thead>
8233
<tbody>
8334
{% for activity in activities %}
8435
<tr>
85-
<td class="text-start">
86-
<span id="display-{{ activity[0] }}">{{ activity[1] }}</span>
87-
88-
<form id="edit-form-{{ activity[0] }}" method="post" action="{{ url_for('edit', activity_id=activity[0]) }}" class="d-none">
89-
<div class="input-group input-group-sm">
90-
<input type="text" name="new_text" class="form-control" value="{{ activity[1] }}" required>
91-
<button type="submit" class="btn btn-success btn-sm">Save</button>
92-
<button type="button" class="btn btn-secondary btn-sm" onclick="toggleEdit('{{ activity[0] }}')"></button>
93-
</div>
36+
<td class="text-start">{{ activity[1] }}</td>
37+
38+
<td class="text-start align-middle p-1" style="width: 110px;">
39+
<form method="post" action="{{ url_for('delete', activity_id=activity[0]) }}" class="d-inline">
40+
<button type="submit" class="sea-btn" style="width: 90px; font-size: 0.9rem;">Delete</button>
9441
</form>
9542
</td>
96-
<td class="text-end">
97-
<div id="actions-{{ activity[0] }}">
98-
<button type="button" class="btn btn-sm btn-outline-primary" onclick="toggleEdit('{{ activity[0] }}')">Edit</button>
99-
100-
<form method="post" action="{{ url_for('delete', activity_id=activity[0]) }}" class="d-inline">
101-
<button type="submit" class="btn btn-sm btn-outline-danger">Delete</button>
102-
</form>
103-
</div>
104-
</td>
10543
</tr>
10644
{% else %}
10745
<tr>
108-
<td colspan="2" class="text-center text-muted fst-italic py-4">No vacation plans yet!</td>
46+
<td colspan="3" class="text-center text-muted fst-italic py-4">No vacation plans yet!</td>
10947
</tr>
11048
{% endfor %}
11149
</tbody>
@@ -114,24 +52,18 @@ <h1 class="display-9 fw-bold sea-title mb-4 text-center">Vacation Planner</h1>
11452
</div>
11553

11654
<script>
117-
function toggleEdit(id) {
118-
const displaySpan = document.getElementById(`display-${id}`);
119-
const editForm = document.getElementById(`edit-form-${id}`);
120-
const actionButtons = document.getElementById(`actions-${id}`);
121-
122-
if (editForm.classList.contains('d-none')) {
123-
// Switch to Edit Mode
124-
editForm.classList.remove('d-none');
125-
displaySpan.classList.add('d-none');
126-
actionButtons.classList.add('d-none');
55+
// Auto-focus logic for the input field
56+
(function () {
57+
const input = document.getElementById('activityInput');
58+
if (!input) return;
59+
if (input.value && input.value.length > 0) {
60+
input.focus();
61+
const len = input.value.length;
62+
input.setSelectionRange(len, len);
12763
} else {
128-
// Switch back to Display Mode
129-
editForm.class
130-
editForm.classList.add('d-none');
131-
displaySpan.classList.remove('d-none');
132-
actionButtons.classList.remove('d-none');
64+
input.focus();
13365
}
134-
}
66+
})();
13567
</script>
13668
</body>
137-
</html>
69+
</html>

0 commit comments

Comments
 (0)