Skip to content

Commit 16ab422

Browse files
authored
Add initial teams feature (#42)
This adds UIs for joining and managing teams. It includes an admin-facing settings page for managing teams and participant-facing landing page for joining teams/invitations. Backend PR: TaskarCenterAtUW/workspaces-backend#1
2 parents bbe2ff9 + 7495bea commit 16ab422

37 files changed

Lines changed: 2326 additions & 619 deletions

Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ FROM node as builder
66
ARG VITE_TDEI_API_URL
77
ARG VITE_TDEI_USER_API_URL
88
ARG VITE_API_URL
9+
ARG VITE_NEW_API_URL
910
ARG VITE_OSM_URL
1011
ARG VITE_RAPID_URL
1112
ARG VITE_PATHWAYS_EDITOR_URL
@@ -29,8 +30,8 @@ COPY --from=builder /app/.output/public /usr/share/nginx/html/
2930
# https://stackoverflow.com/questions/44438637/arg-substitution-in-run-command-not-working-for-dockerfile
3031
ARG CODE_VERSION
3132

32-
RUN echo "This is (frontend, cgimap, osmrails, pathways, rapid, taskingmanager) $CODE_VERSION"
33-
RUN echo "This is (frontend, cgimap, osmrails, pathways, rapid, taskingmanager) $CODE_VERSION" > /usr/share/nginx/html/VERSION
33+
RUN echo "This is (frontend, api, cgimap, osmrails, pathways, rapid, taskingmanager) $CODE_VERSION"
34+
RUN echo "This is (frontend, api, cgimap, osmrails, pathways, rapid, taskingmanager) $CODE_VERSION" > /usr/share/nginx/html/VERSION
3435

3536
RUN chown -R nginx:nginx /usr/share/nginx/html/
3637

app.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<template>
2-
<nuxt-layout>
3-
<nuxt-page />
4-
</nuxt-layout>
2+
<b-app>
3+
<nuxt-layout>
4+
<nuxt-page />
5+
</nuxt-layout>
6+
</b-app>
57
</template>

assets/scss/main.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@import "theme.scss";
22
@import "bootstrap/scss/bootstrap.scss";
33
@import "maplibre-gl/dist/maplibre-gl.css";
4+
@import "vue3-toastify/dist/index.css";
45

56
:root {
67
--ws-create-color: $review-create-color;

components/AppNavbar.vue

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,21 @@
2929
<span class="mx-auto" />
3030

3131
<nuxt-link v-show="!auth.ok" to="/signin" class="btn">Sign In</nuxt-link>
32-
<span v-show="auth.ok" class="nav-item dropdown">
33-
<a class="nav-link" href="#" id="navbarAccountMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
32+
<b-dropdown
33+
v-show="auth.ok"
34+
class="nav-item"
35+
placement="bottom-end"
36+
:variant="null"
37+
is-nav
38+
no-caret
39+
>
40+
<template #button-content>
3441
<app-icon variant="account_circle" size="24" />{{ auth.displayName }}
35-
</a>
36-
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarAccountMenuLink">
37-
<li>
38-
<nuxt-link class="dropdown-item" to="/" @click="auth.clear()">
39-
<app-icon variant="logout" class="me-3" />Logout
40-
</nuxt-link>
41-
</li>
42-
</ul>
43-
</span>
42+
</template>
43+
<b-dropdown-item to="/" @click="auth.clear()">
44+
<app-icon variant="logout" class="me-3" />Logout
45+
</b-dropdown-item>
46+
</b-dropdown>
4447
</div>
4548
</div>
4649
</nav>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<template>
2+
<b-button
3+
:variant="props.variant"
4+
to="/dashboard"
5+
>
6+
Return to Dashboard
7+
</b-button>
8+
</template>
9+
10+
<script setup lang="ts">
11+
import type { BButtonProps } from 'bootstrap-vue-next/types';
12+
13+
interface Props {
14+
variant?: BButtonProps['variant'];
15+
}
16+
17+
const props = withDefaults(defineProps<Props>(), {
18+
variant: 'primary',
19+
});
20+
</script>

components/review/FilterDropdown.vue

Lines changed: 59 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,72 @@
11
<template>
2-
<div class="dropdown ms-auto">
3-
<button
4-
id="reviewSettingsBtn"
5-
type="button"
6-
class="btn btn-light btn-sm border"
7-
data-bs-toggle="dropdown"
8-
aria-haspopup="true"
9-
aria-expanded="false"
10-
>
2+
<b-dropdown
3+
class="ms-auto"
4+
toggle-class="border"
5+
variant="light"
6+
size="sm"
7+
placement="bottom-end"
8+
auto-close="outside"
9+
no-caret
10+
>
11+
<template #button-content>
1112
<app-icon variant="settings" no-margin />
1213
<span class="visually-hidden">Settings</span>
13-
</button>
14+
</template>
1415

15-
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="reviewSettingsBtn">
16-
<div class="px-3 py-2">
17-
<div class="form-check form-switch">
18-
<label class="form-check-label">
19-
<input
20-
v-model="filter.includeChangesets"
21-
type="checkbox"
22-
class="form-check-input"
23-
/>
24-
Changesets
25-
</label>
26-
</div>
27-
<div class="form-check form-switch">
28-
<label class="form-check-label">
29-
<input
30-
v-model="filter.includeFeedback"
31-
type="checkbox"
32-
class="form-check-input"
33-
/>
34-
Feedback
35-
</label>
36-
</div>
37-
<div class="form-check form-switch">
38-
<label class="form-check-label">
39-
<input
40-
v-model="filter.includeNotes"
41-
type="checkbox"
42-
class="form-check-input"
43-
/>
44-
Notes
45-
</label>
46-
</div>
16+
<div class="px-3 py-2">
17+
<div class="form-check form-switch">
18+
<label class="form-check-label">
19+
<input
20+
v-model="filter.includeChangesets"
21+
type="checkbox"
22+
class="form-check-input"
23+
/>
24+
Changesets
25+
</label>
4726
</div>
27+
<div class="form-check form-switch">
28+
<label class="form-check-label">
29+
<input
30+
v-model="filter.includeFeedback"
31+
type="checkbox"
32+
class="form-check-input"
33+
/>
34+
Feedback
35+
</label>
36+
</div>
37+
<div class="form-check form-switch">
38+
<label class="form-check-label">
39+
<input
40+
v-model="filter.includeNotes"
41+
type="checkbox"
42+
class="form-check-input"
43+
/>
44+
Notes
45+
</label>
46+
</div>
47+
</div>
4848

49-
<div class="dropdown-divider" />
49+
<b-dropdown-divider />
5050

51-
<div class="px-3 py-2">
52-
<div class="form-check form-switch">
53-
<label class="form-check-label">
54-
<input
55-
v-model="filter.includeResolved"
56-
type="checkbox"
57-
class="form-check-input"
58-
/>
59-
Show Resolved
60-
</label>
61-
</div>
51+
<div class="px-3 py-2">
52+
<div class="form-check form-switch">
53+
<label class="form-check-label">
54+
<input
55+
v-model="filter.includeResolved"
56+
type="checkbox"
57+
class="form-check-input"
58+
/>
59+
Show Resolved
60+
</label>
6261
</div>
62+
</div>
6363

64-
<div class="dropdown-divider" />
64+
<div class="dropdown-divider" />
6565

66-
<div class="px-3 py-2">
67-
<button class="d-block btn btn-primary btn-sm" @click="apply">Apply</button>
68-
</div>
69-
</div><!-- .dropdown-menu -->
70-
</div><!-- .dropdown -->
66+
<div class="px-3 py-2">
67+
<button class="d-block btn btn-primary btn-sm" @click="apply">Apply</button>
68+
</div>
69+
</b-dropdown>
7170
</template>
7271

7372
<script setup lang="ts">

components/settings/Nav.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<template>
2+
<nav class="list-group mb-4">
3+
<settings-nav-link
4+
to=""
5+
icon="settings"
6+
>
7+
General
8+
</settings-nav-link>
9+
<settings-nav-link
10+
to="/teams"
11+
icon="group"
12+
>
13+
Teams
14+
</settings-nav-link>
15+
</nav>
16+
</template>
17+
18+
<script setup lang="ts">
19+
</script>

components/settings/NavLink.vue

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<template>
2+
<nuxt-link
3+
class="list-group-item"
4+
:class="{ active }"
5+
:to="to"
6+
>
7+
<app-icon :variant="props.icon" />
8+
<slot />
9+
</nuxt-link>
10+
</template>
11+
12+
<script setup lang="ts">
13+
import type { Workspace } from '~/types/workspaces';
14+
15+
interface Props {
16+
to: string;
17+
icon: string;
18+
}
19+
20+
const props = defineProps<Props>();
21+
const route = useRoute();
22+
23+
const workspace = inject<Workspace>('workspace')!;
24+
const to = computed(() => `/workspace/${workspace.id}/settings${props.to}`);
25+
26+
const active = computed(() =>
27+
(route.path.endsWith('/settings') && to.value.endsWith('/settings'))
28+
|| (!to.value.endsWith('/settings') && route.path.startsWith(to.value)));
29+
</script>

0 commit comments

Comments
 (0)