-
+
+
+
+
+
+
+
+
+
Filter Google Summer of Code Projects
+
+
+
+
+
+
+
For more project ideas, click here.
@@ -21,6 +52,9 @@
@@ -21,6 +52,9 @@
+
+ {{ message.noProjectsFound }}
+
{{ project.name }}
@@ -97,6 +131,8 @@
'slow');
})
+ $('.filter-select-fields select').material_select();
+
$('.modal').modal({
dismissible: true, // Modal can be dismissed by clicking outside of the modal
opacity: 0.8, // Opacity of modal background
diff --git a/resources/css/style.css b/resources/css/style.css
index cd39fd17..a989f14e 100644
--- a/resources/css/style.css
+++ b/resources/css/style.css
@@ -1,6 +1,20 @@
+.all-filters-option {
+ position: relative;
+ z-index: 1002;
+ min-width: 350px;
+ margin: 10px 0;
+ background-color: white;
+ box-shadow: 0 0 15px 2px black;
+ border-radius: 20px;
+ -webkit-animation-duration: 1s;
+ animation-duration: 1s;
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+}
.apply-flex {
display: flex;
- justify-content: center;
+ flex-flow: row wrap;
+ align-items: center;
}
.black-shadow {
box-shadow: 0 0 15px 2px black;
@@ -8,6 +22,21 @@
.center-align-text {
text-align: center;
}
+.center-content {
+ justify-content: center;
+}
+.close-filters {
+ right: 6%;
+ margin-top: 1.25rem;
+ position: absolute;
+ z-index: 1003;
+}
+.display-none {
+ display: none;
+}
+.evenly-spread-content {
+ justify-content: space-evenly;
+}
.hash_value_dup {
position: 'absolute';
left: '-9999px';
@@ -42,6 +71,36 @@
.fa-clipboard:hover .hinttext {
visibility: visible;
}
+.filter-projects-inputs {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: space-evenly;
+ margin-top: 1rem;
+}
+.filter-btn {
+ width: 165px;
+ z-index: 0;
+}
+.filter-btn .btn-large {
+ border-radius: 100px;
+ box-shadow: 0 0 10px 1px darkslategray;
+}
+.filters-btns {
+ width: 50%;
+}
+.filters-inputs {
+ justify-content: space-around;
+ padding: 20px 0;
+}
+.filter-select-fields {
+ width: 100%;
+ padding-top: 20px;
+ padding-bottom: 10px;
+ justify-content: space-around;
+}
+i.fa {
+ cursor: pointer;
+}
.project-detail-element > .clickable:hover, .clickable:hover .chip:hover {
cursor: pointer;
background-color: #f3f5f8;
@@ -124,6 +183,11 @@
border: 0;
z-index: 9;
}
+.searchbar {
+ width: 85%;
+ min-width: 340px;
+ margin-top: 0;
+}
.sha256sum_hash {
display: flex;
justify-content: space-evenly;
@@ -136,3 +200,15 @@
#sha256sum_hash_value {
word-wrap: break-word;
}
+@-webkit-keyframes fade-in {
+ 0% {opacity: 0;}
+ 100% {opacity: 1;}
+}
+@keyframes fade-in {
+ 0% {opacity: 0;}
+ 100% {opacity: 1;}
+}
+.fade-in {
+ -webkit-animation-name: fade-in;
+ animation-name: fade-in;
+}
diff --git a/resources/js/app.js b/resources/js/app.js
index 08620498..0a22c397 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -97,21 +97,213 @@
controller: function ($scope, $location, Languages) {
self = this
+ $scope.message = {}
+ $scope.projectFilterOptions = {}
+ $scope.selectedStatusesList = []
+ $scope.selectedTagsList = []
+ $scope.selectedLevelsList = []
+ $scope.selectedInitiativesList = []
+ $scope.selectedCollabsList = []
+
var mapping = {
'': 0,
'crowded': 1,
'in_progress': 2,
- 'completed': 3
+ 'completed': 3,
+ 'disabled': 4
+ }
+
+ self.displayFilters = false
+ $scope.toggleFiltersDisplay = function(){
+ self.displayFilters = !self.displayFilters
+ $('select').material_select();
}
$scope.sortOrder = function(project) {
return mapping[project.status];
}
+ $scope.getFiltersMetadata = function(){
+ $http.get('data/projects.liquid')
+ .then(function (res) {
+ var projects = res.data;
+ angular.forEach(projects, function(project){
+ if (project.status.length === 0){
+ $scope.projectFilterOptions.status.options['NOT YET STARTED'] = 0
+ }
+ angular.forEach(project.status, function(state){
+ $scope.projectFilterOptions.status.options[state.toUpperCase()] = mapping[state]
+ })
+ angular.forEach(project.tags, function(tag){
+ $scope.projectFilterOptions.tags.options[tag] = tag
+ })
+ $scope.projectFilterOptions.difficulty.options[project.difficulty.toUpperCase()] = project.difficulty
+ angular.forEach(project.initiatives, function(initiative){
+ $scope.projectFilterOptions.initiatives.options[initiative] = initiative
+ })
+ angular.forEach(project.collaborating_projects, function(collab){
+ $scope.projectFilterOptions['collab-projects'].options[collab] = collab
+ })
+ })
+ })
+ }
+
+ $scope.initializeSelectorData = function(name, label, model_name){
+ $scope.projectFilterOptions[name] = {
+ label: label, model: model_name,options: {}
+ }
+ }
+
+ $scope.getAllFilters = function () {
+ $scope.initializeSelectorData('status', 'Status', 'selectedStatusesList')
+ $scope.initializeSelectorData('tags', 'Project Tags', 'selectedTagsList')
+ $scope.initializeSelectorData('difficulty', 'Difficulty Level', 'selectedLevelsList')
+ $scope.initializeSelectorData('initiatives', 'Initiatives', 'selectedInitiativesList')
+ $scope.initializeSelectorData('collab-projects', 'Collaborating Projects', 'selectedCollabsList')
+ $scope.getFiltersMetadata()
+ }
+
+ function filterProjectsByStatus(projects){
+ var selectedProjects = []
+ angular.forEach(projects, function(project){
+ if (project.status.length === 0 && !selectedProjects.includes(project)){
+ if (
+ ($scope.selectedStatusesList.includes("0") && project.mentors.length > 0) ||
+ ($scope.selectedStatusesList.includes("4") && project.mentors.length === 0)
+ ){
+ selectedProjects.push(project)
+ }
+ }
+ else {
+ angular.forEach(project.status, function (state) {
+ var mappedState = (mapping[state]).toString()
+ if ($scope.selectedStatusesList.includes(mappedState) && !selectedProjects.includes(project)) {
+ selectedProjects.push(project)
+ }
+ })
+ }
+ })
+ return selectedProjects
+ }
+
+ function filterProjectsByTags(projects){
+ var selectedProjects = []
+ angular.forEach(projects, function(project){
+ angular.forEach(project.tags, function(tag){
+ if ($scope.selectedTagsList.includes(tag) && !selectedProjects.includes(project)){
+ selectedProjects.push(project)
+ }
+ })
+ })
+ return selectedProjects
+ }
+
+ function filterProjectsByDifficulty(projects){
+ var selectedProjects = []
+ angular.forEach(projects, function(project){
+ if ($scope.selectedLevelsList.includes(project.difficulty) && !selectedProjects.includes(project)){
+ selectedProjects.push(project)
+ }
+ })
+ return selectedProjects
+ }
+
+ function filterProjectsByInitiatives(projects){
+ var selectedProjects = []
+ angular.forEach(projects, function(project){
+ angular.forEach(project.initiatives, function(initiative){
+ if ($scope.selectedInitiativesList.includes(initiative) && !selectedProjects.includes(project)){
+ selectedProjects.push(project)
+ }
+ })
+ })
+ return selectedProjects
+ }
+
+ function filterProjectsByCollaboratingProjects(projects){
+ var selectedProjects = []
+ angular.forEach(projects, function(project){
+ angular.forEach(project.collaborating_projects, function(collab){
+ if ($scope.selectedCollabsList.includes(collab) && !selectedProjects.includes(project)){
+ selectedProjects.push(project)
+ }
+ })
+ })
+ return selectedProjects
+ }
+
+ $scope.setModelList = function(filter, list){
+ if (filter === 'status'){
+ $scope.selectedStatusesList = list
+ }
+ else if (filter === 'tags'){
+ $scope.selectedTagsList = list
+ }
+ else if (filter === 'difficulty'){
+ $scope.selectedLevelsList = list
+ }
+ else if (filter === 'initiatives'){
+ $scope.selectedInitiativesList = list
+ }
+ else {
+ $scope.selectedCollabsList = list
+ }
+ }
+
+ function anyFiltersApplied(){
+ return (
+ $scope.selectedStatusesList.length > 0 ||
+ $scope.selectedTagsList.length > 0 ||
+ $scope.selectedLevelsList.length > 0 ||
+ $scope.selectedInitiativesList.length > 0 ||
+ $scope.selectedCollabsList.length > 0
+ )
+ }
+
+ $scope.applyFilters = function(){
+ var filteredProjects = $scope.allProjects
+ if(anyFiltersApplied()){
+ if ($scope.selectedStatusesList.length > 0 && filteredProjects.length > 0) {
+ filteredProjects = filterProjectsByStatus(filteredProjects)
+ }
+ if ($scope.selectedTagsList.length > 0 && filteredProjects.length > 0) {
+ filteredProjects = filterProjectsByTags(filteredProjects)
+ }
+ if ($scope.selectedLevelsList.length > 0 && filteredProjects.length > 0) {
+ filteredProjects = filterProjectsByDifficulty(filteredProjects)
+ }
+ if ($scope.selectedInitiativesList.length > 0 && filteredProjects.length > 0) {
+ filteredProjects = filterProjectsByInitiatives(filteredProjects)
+ }
+ if ($scope.selectedCollabsList.length > 0 && filteredProjects.length > 0) {
+ filteredProjects = filterProjectsByCollaboratingProjects(filteredProjects)
+ }
+ if (filteredProjects.length === 0){
+ $scope.message.noProjectsFound = 'No projects found for your selected filters' +
+ ' options! Please try a different filter search combination.'
+ $scope.projectList = []
+ }
+ else {
+ $scope.projectList = filteredProjects
+ }
+ }
+ else {
+ $scope.projectList = filteredProjects
+ }
+ }
+
+ $scope.clearFilters = function(){
+ $scope.projectList = $scope.allProjects
+ var select = $('select')
+ select.prop('selectedIndex', 0)
+ select.material_select()
+ }
+
$scope.getDefaultProjectsMetadata = function () {
$http.get('data/projects.liquid')
.then(function (res) {
$scope.projectList = res.data;
+ $scope.allProjects = res.data;
$scope.projectRequest();
})
}
@@ -284,6 +476,7 @@
$scope.searchText = search_requested
}
+ $scope.getAllFilters();
},
controllerAs: 'lc'
}