Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,25 @@
# Point these at the TDEI dev environment. Tokens from one environment (dev,
# stage, prod) are NOT interchangeable — all components must target the same
# environment.
VITE_TDEI_API_URL=https://api-dev.tdei.us/api/v1/
VITE_TDEI_USER_API_URL=https://portal-api-dev.tdei.us/api/v1/
# Routed through the Nuxt devProxy (nuxt.config.ts). Direct URLs shown for reference:
# VITE_TDEI_API_URL=https://api-dev.tdei.us/api/v1/
# VITE_TDEI_USER_API_URL=https://portal-api-dev.tdei.us/api/v1/
VITE_TDEI_API_URL=/tdei/v1/
VITE_TDEI_USER_API_URL=/tdei-user/v1/

# --- Workspaces Backend ------------------------------------------------------
# The workspaces-backend service, see: https://github.com/TaskarCenterAtUW/workspaces-backend
# If running locally, edit `nuxt.config.ts` devProxy settings and use local port:
# VITE_API_URL=http://localhost:3000/api/v1/
# VITE_OSM_URL=http://localhost:3000/

# Or point at the shared dev instance if you don't need to run it locally.
VITE_API_URL=https://api.workspaces-dev.sidewalks.washington.edu/api/v1/
VITE_OSM_URL=https://osm.workspaces-dev.sidewalks.washington.edu/
# Routed through the Nuxt devProxy (nuxt.config.ts). Direct URLs shown for reference:
# VITE_API_URL=https://api.workspaces-dev.sidewalks.washington.edu/api/v1/
# VITE_OSM_URL=https://osm.workspaces-dev.sidewalks.washington.edu/
# VITE_NEW_API_URL=https://new-api.workspaces-dev.sidewalks.washington.edu/api/v1/
VITE_API_URL=/api/v1/
VITE_OSM_URL=/osm/
VITE_NEW_API_URL=/new-api/v1/

# --- Embedded Editors ---------------------------------------------------------
# Rapid editor (OSW editing) and Pathways editor (GTFS Pathways editing).
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
# Runs `nuxt prepare` via the postinstall hook, which generates the .nuxt
# types + eslint typegen that both `lint` and `typecheck` rely on.
- name: Install dependencies
run: npm ci
run: npm install

# The quality steps below use `if: ${{ !cancelled() }}` so every check runs
# and reports its own result even when an earlier one fails.
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ logs
/playwright-report/
/blob-report/
/playwright/.cache/
/.claude
/.claude
51 changes: 39 additions & 12 deletions components/review/Discussion.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
</template>

<script setup lang="ts">
import { toast } from 'vue3-toastify';
import type { ReviewListItem } from '~/services/review';
import { osmClient } from '~/services/index';

Expand Down Expand Up @@ -53,16 +54,19 @@ async function refresh() {
}

async function refreshChangeset() {
if (!props.item.hasComments) {
messages.value = [];
return;
}

// getChangesetComments already returns [] when there are none, so don't gate
// on props.item.hasComments — that reads the changeset-list payload's
// comments_count, which is never updated after posting, so a freshly added
// comment would otherwise never appear.
messages.value = await osmClient.getChangesetComments(workspaceId, props.item.id);
}

function refreshNote() {
messages.value = (props.item.data as OsmNote).comments.map(comment => ({
messages.value = noteComments(props.item.data as OsmNote);
}

function noteComments(note: OsmNote): ChatMessage[] {
return note.comments.map(comment => ({
id: Symbol(),
user: comment.user,
date: comment.date,
Expand All @@ -71,15 +75,38 @@ function refreshNote() {
}

async function send(message: string) {
if (props.item.isChangeset) {
await sendChangeset(message);
}
try {
if (props.item.isChangeset) {
await osmClient.postChangesetComment(workspaceId, props.item.id, message);
// Re-fetch so the newly posted comment (and its server timestamp) appears.
await refreshChangeset();
}
else if (props.item.isNote) {
await osmClient.postNoteComment(workspaceId, props.item.id, message);
// Notes have no single-note fetch endpoint, so reflect the just-posted
// comment optimistically rather than re-listing every note.
appendLocalMessage(message);
}

chat.value?.clear();
// Only clear the input once the comment posted, so a failed send keeps the
// user's text.
chat.value?.clear();
}
catch {
toast.error('Failed to post your comment. Please try again.');
}
}

async function sendChangeset(message: string) {
await osmClient.postChangesetComment(workspaceId, props.item.id, message);
function appendLocalMessage(text: string) {
messages.value = [
...messages.value,
{
id: Symbol(),
user: osmClient.auth.displayName || undefined,
date: new Date(),
text
}
];
}
</script>

Expand Down
28 changes: 19 additions & 9 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,34 @@ export default defineNuxtConfig({
'~/assets/scss/main.scss',
],
sourcemap: { client: 'hidden' },
devServer: {
host: '0.0.0.0',
Comment thread
coderabbitai[bot] marked this conversation as resolved.
},
compatibilityDate: '2024-10-24',

nitro: {
// deal with CORS issues during development
// Route every backend the SPA calls through the dev server so requests are
// same-origin — this avoids CORS when browsing under any hostname. Each
// client's base URL (VITE_* in .env) must be the matching relative prefix,
// e.g. VITE_API_URL=/api/v1/, VITE_OSM_URL=/osm/, VITE_TDEI_API_URL=/tdei/v1/.
// `changeOrigin` makes the upstream see its own Host (needed for TLS/vhosts).
devProxy: {
// use these values when you want to use the existing dev backend
'/api': 'https://api.workspaces-dev.sidewalks.washington.edu/api/',
'/workspaces': 'https://osm.workspaces-dev.sidewalks.washington.edu/workspaces/',
'/api': { target: 'https://api.workspaces-dev.sidewalks.washington.edu/api/', changeOrigin: true },
'/new-api': { target: 'https://new-api.workspaces-dev.sidewalks.washington.edu/api/', changeOrigin: true },
'/osm': { target: 'https://osm.workspaces-dev.sidewalks.washington.edu/', changeOrigin: true },
'/tdei': { target: 'https://api-dev.tdei.us/api/', changeOrigin: true },
'/tdei-user': { target: 'https://portal-api-dev.tdei.us/api/', changeOrigin: true },

// use these values when running the backend locally, e.g. the repo workspaces-backend
// '/api': 'http://localhost:8000/api/',
// '/workspaces': 'http://localhost:8000/workspaces/',
// Local backend (repo workspaces-backend) instead of the shared dev API:
// '/api': { target: 'http://localhost:8000/api/', changeOrigin: true },
// '/osm': { target: 'http://localhost:8000/workspaces/', changeOrigin: true },
},
},
vite: {
server: {
allowedHosts: [
'workspaces.local',
'.local',
'.internal',
'.sidewalks.washington.edu',
],
},
optimizeDeps: {
Expand Down
Loading
Loading