@@ -139,7 +136,6 @@ limitations under the License.
import MsgBoxMixin from '../utils/modal/MsgBoxMixin';
import ProjectService from './ProjectService';
import SkillsBTable from '../utils/table/SkillsBTable';
- import SlimDateCell from '../utils/table/SlimDateCell';
import RemovalValidation from '../utils/modal/RemovalValidation';
import EditProject from './EditProject';
@@ -198,11 +194,6 @@ limitations under the License.
label: 'Badges',
sortable: true,
},
- {
- key: 'lastReportedSkill',
- label: 'Last Reported Skill',
- sortable: true,
- },
{
key: 'created',
label: 'Created',
@@ -227,7 +218,6 @@ limitations under the License.
components: {
EditProject,
SkillsBTable,
- SlimDateCell,
RemovalValidation,
},
mounted() {
diff --git a/e2e-tests/cypress/integration/projects_spec.js b/e2e-tests/cypress/integration/projects_spec.js
index f42f93608b..7ed6783692 100644
--- a/e2e-tests/cypress/integration/projects_spec.js
+++ b/e2e-tests/cypress/integration/projects_spec.js
@@ -909,32 +909,11 @@ describe('Projects Tests', () => {
cy.wait('@getProjects');
cy.wait('@loadInception');
- cy.get('[data-cy=projectCreated]').should('be.visible').contains('Today');
- cy.get('[data-cy=projectLastReportedSkill]').should('be.visible').contains('Never');
-
- const now = dayjs().utc();
- cy.reportSkill('my_project_123', 1, 'user@skills.org', now.subtract(1, 'year').format('YYYY-MM-DD HH:mm'), false);
-
- cy.visit('/administrator/');
- cy.wait('@getProjects');
- cy.wait('@loadInception');
- cy.get('[data-cy=projectCreated]').should('be.visible').contains('Today');
- cy.get('[data-cy=projectLastReportedSkill]').should('be.visible').contains('a year ago');
-
- cy.reportSkill('my_project_123', 1, 'user@skills.org', now.subtract(2, 'months').format('YYYY-MM-DD HH:mm'), false);
- cy.visit('/administrator/');
- cy.wait('@getProjects');
- cy.wait('@loadInception');
- cy.get('[data-cy=projectCreated]').should('be.visible').contains('Today');
- cy.get('[data-cy=projectLastReportedSkill]').should('be.visible').contains('2 months ago');
-
- cy.reportSkill('my_project_123', 1, 'user@skills.org', now.subtract(7, 'days').utc().format('YYYY-MM-DD HH:mm'), false);
-
- cy.visit('/administrator/');
- cy.wait('@getProjects');
- cy.wait('@loadInception');
- cy.get('[data-cy=projectCreated]').should('be.visible').contains('Today');
- cy.get('[data-cy=projectLastReportedSkill]').should('be.visible').contains('7 days ago');
+ cy.get('[data-cy=projectCreated]')
+ .should('be.visible')
+ .contains('Today');
+ cy.get('[data-cy=projectLastReportedSkill]')
+ .should('not.exist');
});
it('Created and Last Reported Skill data should be visible on project page', () => {
diff --git a/e2e-tests/cypress/integration/projects_table_spec.js b/e2e-tests/cypress/integration/projects_table_spec.js
index ce8af6b7c9..e8c0be3f74 100644
--- a/e2e-tests/cypress/integration/projects_table_spec.js
+++ b/e2e-tests/cypress/integration/projects_table_spec.js
@@ -325,10 +325,6 @@ describe('Projects Table Tests', () => {
colIndex: 4,
value: '0'
},
- {
- colIndex: 5,
- value: '2 months ago'
- },
],
], 1);
});
diff --git a/service/src/main/java/skills/controller/AdminController.groovy b/service/src/main/java/skills/controller/AdminController.groovy
index f17a80c9a6..299fb09ff0 100644
--- a/service/src/main/java/skills/controller/AdminController.groovy
+++ b/service/src/main/java/skills/controller/AdminController.groovy
@@ -1412,6 +1412,12 @@ class AdminController {
return success
}
+ @RequestMapping(value = "/projects/{projectId}/lastSkillEvent", method = RequestMethod.GET, produces = "application/json")
+ LatestEvent getLatestEventForProject(@PathVariable("projectId") String projectId) {
+ SkillsValidator.isNotBlank(projectId, "projectId")
+ return projAdminService.getLastReportedSkillEvent(projectId)
+ }
+
}
diff --git a/service/src/main/java/skills/controller/result/model/LatestEvent.groovy b/service/src/main/java/skills/controller/result/model/LatestEvent.groovy
new file mode 100644
index 0000000000..35f4d4ab72
--- /dev/null
+++ b/service/src/main/java/skills/controller/result/model/LatestEvent.groovy
@@ -0,0 +1,20 @@
+/**
+ * Copyright 2020 SkillTree
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package skills.controller.result.model
+
+class LatestEvent {
+ Date lastReportedSkillDate
+}
diff --git a/service/src/main/java/skills/services/admin/ProjAdminService.groovy b/service/src/main/java/skills/services/admin/ProjAdminService.groovy
index e384d69fde..9bf317de15 100644
--- a/service/src/main/java/skills/services/admin/ProjAdminService.groovy
+++ b/service/src/main/java/skills/services/admin/ProjAdminService.groovy
@@ -31,6 +31,7 @@ import skills.controller.exceptions.ErrorCode
import skills.controller.exceptions.SkillException
import skills.controller.request.model.*
import skills.controller.result.model.CustomIconResult
+import skills.controller.result.model.LatestEvent
import skills.controller.result.model.ProjectResult
import skills.controller.result.model.SettingsResult
import skills.controller.result.model.SimpleProjectResult
@@ -544,11 +545,16 @@ class ProjAdminService {
}
@Profile
- private UserInfo loadCurrentUser(boolean failIfNoCurrentUser=true) {
+ private UserInfo loadCurrentUser(boolean failIfNoCurrentUser = true) {
UserInfo currentUser = userInfoService.getCurrentUser()
if (!currentUser && failIfNoCurrentUser) {
throw new SkillsAuthorizationException('No current user found')
}
return currentUser
}
+
+ LatestEvent getLastReportedSkillEvent(String projectId) {
+ Date date = eventsRepo.getLatestEventDateForProject(projectId)
+ new LatestEvent(lastReportedSkillDate: date)
+ }
}
diff --git a/service/src/main/java/skills/storage/repos/ProjDefRepo.groovy b/service/src/main/java/skills/storage/repos/ProjDefRepo.groovy
index 2b5b97a18b..8339667ca6 100644
--- a/service/src/main/java/skills/storage/repos/ProjDefRepo.groovy
+++ b/service/src/main/java/skills/storage/repos/ProjDefRepo.groovy
@@ -114,11 +114,9 @@ interface ProjDefRepo extends CrudRepository
{
COALESCE(reusedSkills.reusedSkillCount, 0) AS numSkillsReused,
COALESCE(reusedSkills.reusedTotalPoints, 0) AS totalPointsReused,
expiration.expirationTriggeredDate as expirationTriggered,
- events.latest AS lastReportedSkill,
pd.created,
GREATEST(skills.skillUpdated, badges.badgeUpdated, subjects.subjectUpdated, pd.updated) as lastEdited
FROM project_definition pd
- LEFT JOIN (SELECT max(project_id) as project_id, MAX(event_time) AS latest FROM user_events where LOWER(project_id) = LOWER(?1)) events ON events.project_id = pd.project_id
LEFT JOIN (SELECT max(project_id) as project_id, COUNT(id) AS errorCount FROM project_error where LOWER(project_id) = LOWER(?1)) errors ON errors.project_id = pd.project_id
LEFT JOIN (SELECT max(project_id) as project_id, COUNT(id) AS skillCount, MAX(updated) as skillUpdated FROM skill_definition WHERE type = 'Skill' and enabled = 'false' and LOWER(project_id) = LOWER(?1)) disabledSkills ON disabledSkills.project_id = pd.project_id
LEFT JOIN (SELECT max(project_id) AS project_id, COUNT(id) AS skillCount, MAX(updated) as skillUpdated FROM skill_definition WHERE type = 'Skill' and enabled = 'true' and skill_id not like '%STREUSESKILLST%' and LOWER(project_id) = LOWER(?1)) skills ON skills.project_id = pd.project_id
@@ -181,12 +179,10 @@ interface ProjDefRepo extends CrudRepository {
COALESCE(groups.groupCount, 0) AS numGroups,
CAST(COALESCE(expiration.expiringUnused, 'false') AS BOOLEAN) as expiring,
expiration.expirationTriggeredDate as expirationTriggered,
- events.latest AS lastReportedSkill,
reusedSkills.skillCount AS numSkillsReused,
reusedSkills.totalPoints AS totalPointsReused,
pd.created
FROM project_definition pd
- LEFT JOIN (SELECT project_id, MAX(event_time) AS latest FROM user_events GROUP BY project_id) events ON events.project_id = pd.project_id
LEFT JOIN (SELECT project_id, COUNT(id) AS errorCount FROM project_error GROUP BY project_id) errors ON errors.project_id = pd.project_id
LEFT JOIN (SELECT project_id, COUNT(id) AS skillCount FROM skill_definition WHERE type = 'Skill' and skill_id not like '%STREUSESKILLST%' and enabled = 'true' GROUP BY project_id) skills ON skills.project_id = pd.project_id
LEFT JOIN (SELECT project_id, COUNT(id) AS skillCount, sum(total_points) as totalPoints FROM skill_definition WHERE type = 'Skill' and skill_id like '%STREUSESKILLST%' and enabled = 'true' GROUP BY project_id) reusedSkills ON reusedSkills.project_id = pd.project_id
diff --git a/service/src/main/java/skills/storage/repos/UserEventsRepo.groovy b/service/src/main/java/skills/storage/repos/UserEventsRepo.groovy
index 75607750c5..478c68543f 100644
--- a/service/src/main/java/skills/storage/repos/UserEventsRepo.groovy
+++ b/service/src/main/java/skills/storage/repos/UserEventsRepo.groovy
@@ -469,4 +469,10 @@ interface UserEventsRepo extends CrudRepository {
) AS counts GROUP BY counts.countBucket;
''', nativeQuery = true)
public List binnedUserCountsForSkillUsagePostAchievement(@Param("skillRefId") Integer skillRefId)
+
+ @Nullable
+ @Query(value = '''
+ SELECT max(event_time) FROM user_events where project_id = ?1
+ ''', nativeQuery = true)
+ Date getLatestEventDateForProject(String projectId)
}
diff --git a/service/src/test/java/skills/intTests/UserAdminMetricsSpec.groovy b/service/src/test/java/skills/intTests/UserAdminMetricsSpec.groovy
index aa9884f201..4a78db01ef 100644
--- a/service/src/test/java/skills/intTests/UserAdminMetricsSpec.groovy
+++ b/service/src/test/java/skills/intTests/UserAdminMetricsSpec.groovy
@@ -61,4 +61,48 @@ class UserAdminMetricsSpec extends DefaultIntSpec {
metrics.numSkills == 2
metrics.userTotalPoints == 70
}
+
+ def "get latest event date for a project"() {
+ List users = getRandomUsers(3)
+
+ def proj1 = SkillsFactory.createProject(1)
+ def proj1_subj = SkillsFactory.createSubject(1, 1)
+ List