Skip to content

Commit fd95e0a

Browse files
committed
Fixed task selection highlighting issue & other minor fixes
1 parent 73331b2 commit fd95e0a

5 files changed

Lines changed: 64 additions & 53 deletions

File tree

components/project-wizard/steps/ReviewStep.vue

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ function formatRole(role: WorkspaceRole) {
137137
margin: 0;
138138
text-align: left;
139139
font-family: Lato, var(--primary-font-family), sans-serif;
140-
font-size: 18px;
140+
font-size: 1.125rem;
141141
font-style: normal;
142142
font-weight: 600;
143-
line-height: 22px;
143+
line-height: 1.375rem;
144144
letter-spacing: 0;
145145
color: #1a1e3d;
146146
opacity: 1;
@@ -150,10 +150,10 @@ function formatRole(role: WorkspaceRole) {
150150
margin: 0;
151151
text-align: left;
152152
font-family: Lato, var(--primary-font-family), sans-serif;
153-
font-size: 18px;
153+
font-size: 1.125rem;
154154
font-style: normal;
155155
font-weight: 400;
156-
line-height: 26px;
156+
line-height: 1.625rem;
157157
letter-spacing: 0;
158158
color: #5a607b;
159159
opacity: 1;
@@ -165,10 +165,10 @@ function formatRole(role: WorkspaceRole) {
165165
gap: 0.35rem;
166166
text-align: left;
167167
font-family: Lato, var(--primary-font-family), sans-serif;
168-
font-size: 18px;
168+
font-size: 1.125rem;
169169
font-style: normal;
170170
font-weight: 400;
171-
line-height: 26px;
171+
line-height: 1.625rem;
172172
letter-spacing: 0;
173173
color: #5a607b;
174174
opacity: 1;
@@ -186,10 +186,10 @@ function formatRole(role: WorkspaceRole) {
186186
gap: 0.55rem;
187187
color: #5a607b;
188188
font-family: Lato, var(--primary-font-family), sans-serif;
189-
font-size: 18px;
189+
font-size: 1.125rem;
190190
font-style: normal;
191191
font-weight: 400;
192-
line-height: 26px;
192+
line-height: 1.625rem;
193193
}
194194
195195
.project-wizard-review-validator-avatar {
@@ -217,9 +217,9 @@ function formatRole(role: WorkspaceRole) {
217217
.project-wizard-review-instructions {
218218
color: #5a607b;
219219
font-family: Lato, var(--primary-font-family), sans-serif;
220-
font-size: 18px;
220+
font-size: 1.125rem;
221221
font-style: normal;
222222
font-weight: 400;
223-
line-height: 26px;
223+
line-height: 1.625rem;
224224
}
225225
</style>

components/workspace-project-details/ProjectMap.vue

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -151,22 +151,30 @@ const showLegend = computed(() =>
151151
|| Boolean(props.taskGrid?.features.length),
152152
);
153153
154-
const taskFeatureCollection = computed<FeatureCollection<Polygon>>(() => ({
155-
type: 'FeatureCollection',
156-
features: props.tasks
157-
.filter(task => task.geometry)
158-
.map(task => ({
159-
type: 'Feature',
160-
geometry: task.geometry as Polygon,
161-
properties: {
162-
id: task.id,
163-
selected: task.id === props.selectedTaskId,
164-
status: task.status,
165-
taskNumber: task.taskNumber,
166-
locked: task.locked,
167-
},
168-
})),
169-
}));
154+
const taskFeatureCollection = computed<FeatureCollection<Polygon>>(() => {
155+
const sortedTasks = [...props.tasks].sort((a, b) => {
156+
const aSelected = a.id === props.selectedTaskId ? 1 : 0;
157+
const bSelected = b.id === props.selectedTaskId ? 1 : 0;
158+
return aSelected - bSelected;
159+
});
160+
161+
return {
162+
type: 'FeatureCollection',
163+
features: sortedTasks
164+
.filter(task => task.geometry)
165+
.map(task => ({
166+
type: 'Feature',
167+
geometry: task.geometry as Polygon,
168+
properties: {
169+
id: task.id,
170+
selected: task.id === props.selectedTaskId,
171+
status: task.status,
172+
taskNumber: task.taskNumber,
173+
locked: task.locked,
174+
},
175+
})),
176+
};
177+
});
170178
171179
const aoiOutlineFeatureCollection = computed<FeatureCollection<LineString | MultiLineString>>(() => ({
172180
type: 'FeatureCollection',
@@ -350,8 +358,8 @@ function ensureLayers() {
350358
'fill-opacity': [
351359
'case',
352360
['==', ['get', 'selected'], true],
353-
0.94,
354-
0.82,
361+
0.9,
362+
0.45,
355363
],
356364
},
357365
};
@@ -364,7 +372,7 @@ function ensureLayers() {
364372
'line-color': [
365373
'case',
366374
['==', ['get', 'selected'], true],
367-
'#2f3858',
375+
'#2f3661',
368376
[
369377
'match',
370378
['coalesce', ['get', 'status'], 'ready_for_mapping'],
@@ -377,8 +385,8 @@ function ensureLayers() {
377385
'line-width': [
378386
'case',
379387
['==', ['get', 'selected'], true],
380-
2.6,
381-
2.4,
388+
4.5,
389+
1.5,
382390
],
383391
'line-opacity': 1,
384392
},

composables/useProjectRole.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import type { WorkspaceRole } from '~/types/workspaces';
1111
*
1212
* Returns reactive computed flags for all permission checks needed across the project UI.
1313
*/
14-
export async function useProjectRole(
14+
export function useProjectRole(
1515
workspaceId: number,
1616
projectId: string,
1717
currentUserId: string | null,
@@ -20,19 +20,6 @@ export async function useProjectRole(
2020
// Fetch the user's explicit project-level role. Returns null if none is assigned (404).
2121
const projectRole = ref<WorkspaceProjectContributorRole | null>(null);
2222

23-
if (currentUserId) {
24-
try {
25-
projectRole.value = await workspaceProjectsClient.getWorkspaceProjectUserRole(
26-
workspaceId,
27-
projectId,
28-
currentUserId,
29-
);
30-
}
31-
catch {
32-
projectRole.value = null;
33-
}
34-
}
35-
3623
/**
3724
* The effective role is the highest-privilege role the user holds.
3825
* Workspace lead always takes precedence over any project-level role.
@@ -73,6 +60,21 @@ export async function useProjectRole(
7360

7461
const isExplicitProjectLead = computed(() => projectRole.value === 'lead');
7562

63+
const promise = (async () => {
64+
if (currentUserId) {
65+
try {
66+
projectRole.value = await workspaceProjectsClient.getWorkspaceProjectUserRole(
67+
workspaceId,
68+
projectId,
69+
currentUserId,
70+
);
71+
}
72+
catch {
73+
projectRole.value = null;
74+
}
75+
}
76+
})();
77+
7678
return {
7779
effectiveRole,
7880
isProjectLead,
@@ -81,5 +83,6 @@ export async function useProjectRole(
8183
canValidate,
8284
canMap,
8385
canManageContributors,
86+
promise,
8487
};
8588
}

pages/workspace/[id]/projects/[projectId]/index.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,14 @@ const {
259259
canValidate,
260260
canMap,
261261
canManageContributors,
262-
} = await useProjectRole(
262+
promise: rolePromise,
263+
} = useProjectRole(
263264
workspaceId,
264265
projectId,
265266
currentUserIdForRole,
266267
workspace.role,
267268
);
269+
await rolePromise;
268270
269271
/**
270272
* The Contributors tab is only visible to project leads.

services/project-wizard-review.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import DOMPurify from 'dompurify';
2+
13
import { calculateProjectWizardAoiAreaSquareKilometers } from '~/services/project-wizard-aoi';
24

35
import type {
@@ -48,13 +50,9 @@ export function sanitizeReviewHtml(html: string): string {
4850
return '';
4951
}
5052

51-
return html
52-
.replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi, '')
53-
.replace(/<style[\s\S]*?>[\s\S]*?<\/style>/gi, '')
54-
.replace(/\son[a-z]+="[^"]*"/gi, '')
55-
.replace(/\son[a-z]+='[^']*'/gi, '')
56-
.replace(/\s(href|src)\s*=\s*(['"])javascript:[\s\S]*?\2/gi, '')
57-
.trim();
53+
return typeof window !== 'undefined'
54+
? DOMPurify.sanitize(html, { USE_PROFILES: { html: true } })
55+
: html;
5856
}
5957

6058
function formatSquareKilometers(value: number): string {

0 commit comments

Comments
 (0)