67
67
save-button-text =" Create"
68
68
:title =" $t('newProject')"
69
69
event-name =" i-project"
70
+ @close =" onNewProjectDialogueClosed()"
70
71
>
71
72
<template v-slot :form =" { onSave , onError , needSave , needReset } " >
72
73
<ProjectForm
80
81
</template >
81
82
</EditDialog >
82
83
84
+ <EditDialog
85
+ v-model =" subscriptionDialog"
86
+ :save-button-text =" user.admin && !user.has_active_subscription ? 'Activate' : 'Reactivate'"
87
+ v-if =" user"
88
+ event-name =" i-user"
89
+ dont-close-on-save
90
+ >
91
+ <template v-slot :title =" {} " >
92
+ <v-icon
93
+ large
94
+ class =" mr-2"
95
+ color =" #f14668"
96
+ >
97
+ mdi-professional-hexagon
98
+ </v-icon >
99
+ Subscription details
100
+ </template >
101
+
102
+ <template v-slot :form =" { onSave , onError , needSave , needReset } " >
103
+ <SubscriptionForm
104
+ item-id =" new"
105
+ @save =" onSave(); onSubscriptionKeyUpdates();"
106
+ @error =" onError"
107
+ :need-save =" needSave"
108
+ :need-reset =" needReset"
109
+ />
110
+ </template >
111
+ </EditDialog >
112
+
83
113
<EditDialog
84
114
v-model =" restoreProjectDialog"
85
115
save-button-text =" Restore"
174
204
<v-list-item-content >{{ item.name }}</v-list-item-content >
175
205
</v-list-item >
176
206
207
+ <v-divider v-if =" user.can_create_project" />
208
+
177
209
<v-list-item
178
- @click =" newProjectDialog = true; newProjectType = ''; "
210
+ @click =" showNewProjectDialogue() "
179
211
v-if =" user.can_create_project"
180
212
data-testid =" sidebar-newProject"
181
213
>
364
396
<template v-slot :append >
365
397
<v-list class =" pa-0" >
366
398
399
+ <v-list-item
400
+ key =" premium"
401
+ v-if =" user.admin && !user.has_active_subscription"
402
+ @click =" subscriptionDialog = true"
403
+ class =" ActivatePremiumSubscriptionButton"
404
+ >
405
+ <v-list-item-content >
406
+ <v-list-item-title
407
+ style =" font-weight : bold ; color : white ; font-size : 18px ; text-align : center ;"
408
+ >
409
+ <v-icon
410
+ color =" white"
411
+ x-large
412
+ >mdi-professional-hexagon</v-icon >
413
+ Activate Subscription
414
+ </v-list-item-title >
415
+ </v-list-item-content >
416
+ </v-list-item >
417
+
367
418
<v-list-item >
368
419
<v-switch
369
420
class =" DarkModeSwitch"
458
509
459
510
<v-divider />
460
511
512
+ <v-list-item
513
+ key =" runners"
514
+ to =" /runners"
515
+ v-if =" user.admin"
516
+ >
517
+ <v-list-item-icon >
518
+ <v-icon >mdi-cogs</v-icon >
519
+ </v-list-item-icon >
520
+
521
+ <v-list-item-content >
522
+ {{ $t('runners') }}
523
+ </v-list-item-content >
524
+ </v-list-item >
525
+
461
526
<v-list-item
462
527
key =" tasks"
463
528
to =" /tasks"
473
538
</v-list-item >
474
539
475
540
<v-list-item
476
- key =" runners"
477
- to =" /runners"
541
+ key =" subscription"
478
542
v-if =" user.admin"
543
+ @click =" subscriptionDialog = true"
479
544
>
480
545
<v-list-item-icon >
481
- <v-icon >mdi-cogs</v-icon >
546
+ <v-icon
547
+ color =" #f14668"
548
+ style =" transform : scale (1.4 )"
549
+ >
550
+ mdi-professional-hexagon
551
+ </v-icon >
482
552
</v-list-item-icon >
483
553
484
554
<v-list-item-content >
485
- {{ $t('runners') }}
555
+ Subscription details
486
556
</v-list-item-content >
487
557
</v-list-item >
488
558
604
674
<v-app v-else ></v-app >
605
675
</template >
606
676
<style lang="scss">
677
+ .NewProSubscriptionMenuItem {
678
+ transition : 0.2s transform ;
679
+ .v-list-item__content , .v-list-item__icon {
680
+ transition : 0.5s transform ;
681
+ }
682
+ & :hover {
683
+
684
+ transform : scale (1.05 ) translateY (-1px );
685
+
686
+ // .v-list-item__content {
687
+ // transform: scale(1.05) translateX(2px);
688
+ // }
689
+ .v-list-item__icon {
690
+ // transform: rotate(-360deg);
691
+ }
692
+ }
693
+ }
694
+ .ActivatePremiumSubscriptionButton {
695
+ background : hsl (348deg , 86% , 61% );
696
+ transform : rotate (-5deg ) scale (0.95 );
697
+ border-radius : 6px ;
698
+ transition : 0.2s transform ;
699
+ & :hover {
700
+ transform : rotate (-5deg ) scale (1 );
701
+ }
702
+ }
607
703
608
704
.theme--dark {
609
705
--highlighted-card-bg-color : #262626 ;
@@ -827,6 +923,8 @@ import ProjectForm from '@/components/ProjectForm.vue';
827
923
import UserForm from ' @/components/UserForm.vue' ;
828
924
import EventBus from ' @/event-bus' ;
829
925
import socket from ' @/socket' ;
926
+
927
+ import SubscriptionForm from ' @/components/SubscriptionForm.vue' ;
830
928
import RestoreProjectForm from ' @/components/RestoreProjectForm.vue' ;
831
929
import YesNoDialog from ' @/components/YesNoDialog.vue' ;
832
930
import TaskLogDialog from ' @/components/TaskLogDialog.vue' ;
@@ -907,6 +1005,7 @@ function getSystemLang() {
907
1005
export default {
908
1006
name: ' App' ,
909
1007
components: {
1008
+ SubscriptionForm,
910
1009
TaskLogDialog,
911
1010
YesNoDialog,
912
1011
RestoreProjectForm,
@@ -929,6 +1028,9 @@ export default {
929
1028
newProjectType: ' ' ,
930
1029
userDialog: null ,
931
1030
hideUserDialogButtons: false ,
1031
+
1032
+ subscriptionDialog: null ,
1033
+
932
1034
restoreProjectDialog: null ,
933
1035
restoreProjectResult: null ,
934
1036
restoreProjectResultDialog: null ,
@@ -956,8 +1058,14 @@ export default {
956
1058
async projects (val ) {
957
1059
if (val .length === 0
958
1060
&& this .$route .path .startsWith (' /project/' )
959
- && this .$route .path !== ' /project/new' ) {
960
- await this .$router .push ({ path: ' /project/new' });
1061
+ && this .$route .path !== ' /project/new'
1062
+ && this .$route .path !== ' /project/premium'
1063
+ ) {
1064
+ if (this .$route .query .new_project === ' premium' ) {
1065
+ await this .$router .push ({ path: ' /project/premium' });
1066
+ } else {
1067
+ await this .$router .push ({ path: ' /project/new' });
1068
+ }
961
1069
}
962
1070
},
963
1071
@@ -970,6 +1078,10 @@ export default {
970
1078
EventBus .$emit (' i-show-task' , { taskId });
971
1079
}
972
1080
}
1081
+
1082
+ if ((this .projects || []).length > 0 && this .$route .query .new_project ) {
1083
+ EventBus .$emit (' i-new-project' , { projectType: this .$route .query .new_project });
1084
+ }
973
1085
},
974
1086
975
1087
darkMode (val ) {
@@ -1058,6 +1170,12 @@ export default {
1058
1170
this .drawer = true ;
1059
1171
});
1060
1172
1173
+ EventBus .$on (' i-new-project' , (e ) => {
1174
+ setTimeout (() => {
1175
+ this .showNewProjectDialogue (e .projectType );
1176
+ }, 500 );
1177
+ });
1178
+
1061
1179
EventBus .$on (' i-show-task' , async (e ) => {
1062
1180
if (parseInt (this .$route .query .t || ' ' , 10 ) !== e .taskId ) {
1063
1181
const query = { ... this .$route .query , t: e .taskId };
@@ -1147,7 +1265,7 @@ export default {
1147
1265
switch (e .action ) {
1148
1266
case ' new' :
1149
1267
case ' restore' :
1150
- await this .selectProject (e .item .id );
1268
+ await this .selectProject (e .item .id , { new_project : undefined } );
1151
1269
break ;
1152
1270
case ' delete' :
1153
1271
if (this .projectId === e .item .id && this .projects .length > 0 ) {
@@ -1171,11 +1289,21 @@ export default {
1171
1289
await this .loadUserInfo ();
1172
1290
},
1173
1291
1292
+ showNewProjectDialogue (projectType = ' ' ) {
1293
+ this .newProjectDialog = true ;
1294
+ this .newProjectType = projectType;
1295
+ },
1296
+
1174
1297
selectLanguage (lang ) {
1175
1298
localStorage .setItem (' lang' , lang);
1176
1299
window .location .reload ();
1177
1300
},
1178
1301
1302
+ async onNewProjectDialogueClosed () {
1303
+ const query = { ... this .$route .query , new_project: undefined };
1304
+ await this .$router .replace ({ query });
1305
+ },
1306
+
1179
1307
async onTaskLogDialogClosed () {
1180
1308
const query = { ... this .$route .query , t: undefined };
1181
1309
await this .$router .replace ({ query });
@@ -1237,7 +1365,7 @@ export default {
1237
1365
}
1238
1366
},
1239
1367
1240
- async selectProject (projectId ) {
1368
+ async selectProject (projectId , overriderQuery = {} ) {
1241
1369
this .userRole = (await axios ({
1242
1370
method: ' get' ,
1243
1371
url: ` /api/project/${ projectId} /role` ,
@@ -1249,7 +1377,25 @@ export default {
1249
1377
return ;
1250
1378
}
1251
1379
1252
- await this .$router .push ({ path: ` /project/${ projectId} ` });
1380
+ let query = {};
1381
+
1382
+ switch (this .$route .path ) {
1383
+ case ' /project/new' :
1384
+ query .new_project = ' ' ;
1385
+ break ;
1386
+ default :
1387
+ break ;
1388
+ }
1389
+
1390
+ query = {
1391
+ ... query,
1392
+ ... overriderQuery,
1393
+ };
1394
+
1395
+ await this .$router .push ({
1396
+ path: ` /project/${ projectId}${ window .location .search } ` ,
1397
+ query,
1398
+ });
1253
1399
},
1254
1400
1255
1401
async loadProjects () {
0 commit comments