channel deletion

* only if there aren't any versions attached
This commit is contained in:
Jake Potrebic 2021-03-20 14:34:40 -07:00
parent 1bbe90ff99
commit dfb8189c39
No known key found for this signature in database
GPG Key ID: 7C58557EC9C421F8
6 changed files with 51 additions and 12 deletions

View File

@ -353,6 +353,7 @@ const msgs: LocaleMessageObject = {
duplicateColor: 'This project already has a channel with this color',
duplicateName: 'This project already has a channel with this name',
tooLongName: 'Channel name is too long',
cannotDelete: 'You cannot delete this channel',
},
},
manage: {

View File

@ -11,7 +11,7 @@
<th><v-icon small left>mdi-format-list-numbered</v-icon>{{ $t('channel.manage.versionCount') }}</th>
<th><v-icon small left>mdi-file-find</v-icon>{{ $t('channel.manage.reviewed') }}</th>
<th><v-icon small left>mdi-pencil</v-icon>{{ $t('channel.manage.edit') }}</th>
<th><v-icon small left>mdi-delete</v-icon>{{ $t('channel.manage.trash') }}</th>
<th v-if="channels.length !== 1"><v-icon small left>mdi-delete</v-icon>{{ $t('channel.manage.trash') }}</th>
</tr>
</thead>
<tbody>
@ -31,9 +31,10 @@
</template>
</ChannelModal>
</td>
<td>
<!-- todo we need to properly think about how channel deletion works -->
<v-btn small color="error" @click="deleteChannel(channel.name)">{{ $t('channel.manage.deleteButton') }}</v-btn>
<td v-if="channels.length !== 1">
<v-btn v-if="channel.versionCount === 0" small color="error" @click="deleteChannel(channel)">
{{ $t('channel.manage.deleteButton') }}
</v-btn>
</td>
</tr>
</tbody>
@ -80,10 +81,9 @@ export default class ProjectChannelsPage extends HangarProjectMixin {
editChannel(channel: ProjectChannel) {
if (!channel.id) return;
const id = channel.id;
this.$api
.requestInternal(`channels/${this.project.id}/edit`, true, 'post', {
id,
id: channel.id,
name: channel.name,
color: channel.color,
nonReviewed: channel.nonReviewed,
@ -94,9 +94,14 @@ export default class ProjectChannelsPage extends HangarProjectMixin {
.catch(this.$util.handleRequestError);
}
// TODO deleteChannel
deleteChannel(name: String) {
console.log('delete channel ', name);
deleteChannel(channel: ProjectChannel) {
if (!channel.id) return;
this.$api
.requestInternal(`channels/${this.project.id}/delete/${channel.id}`, true, 'post')
.then(() => {
this.$nuxt.refresh();
})
.catch(this.$util.handleRequestError);
}
addChannel(channel: ProjectChannel) {

View File

@ -51,7 +51,7 @@ public class ChannelController extends HangarController {
}
@Unlocked
@ResponseStatus(HttpStatus.OK)
@ResponseStatus(HttpStatus.CREATED)
@PermissionRequired(type = PermissionType.PROJECT, perms = NamedPermission.EDIT_TAGS, args = "{#projectId}")
@PostMapping(path = "/{projectId}/create", consumes = MediaType.APPLICATION_JSON_VALUE)
public void createChannel(@PathVariable long projectId, @Valid @RequestBody ChannelForm channelForm) {
@ -65,4 +65,12 @@ public class ChannelController extends HangarController {
public void editChannel(@PathVariable long projectId, @Valid @RequestBody EditChannelForm channelForm) {
channelService.editProjectChannel(channelForm.getId(), channelForm.getName(), channelForm.getColor(), projectId, channelForm.isNonReviewed());
}
@Unlocked
@ResponseStatus(HttpStatus.OK)
@PermissionRequired(type = PermissionType.PROJECT,perms = NamedPermission.EDIT_TAGS, args = "{#projectId}")
@PostMapping("/{projectId}/delete/{channelId}")
public void deleteChannel(@PathVariable long projectId, @PathVariable long channelId) {
channelService.deleteProjectChannel(projectId, channelId);
}
}

View File

@ -100,6 +100,13 @@ public interface HangarProjectsDAO {
" WHERE lower(p.owner_name) = lower(:author) AND lower(p.slug) = lower(:slug)")
List<HangarProjectFlag> getHangarProjectFlags(String author, String slug);
@RegisterConstructorMapper(HangarChannel.class)
@SqlQuery("SELECT pc.*," +
" (SELECT count(*) FROM project_versions pv WHERE pv.channel_id = pc.id) as version_count" +
" FROM project_channels pc" +
" WHERE pc.id = :channelId")
HangarChannel getHangarChannel(long channelId);
@RegisterConstructorMapper(HangarChannel.class)
@SqlQuery("SELECT pc.*," +
" (SELECT count(*) FROM project_versions pv WHERE pv.channel_id = pc.id) as version_count" +

View File

@ -25,6 +25,9 @@ public interface ProjectChannelsDAO {
@SqlUpdate("UPDATE project_channels SET name = :name, color = :color, non_reviewed = :nonReviewed WHERE id = :id")
void update(@BindBean ProjectChannelTable projectChannelTable);
@SqlUpdate("DELETE FROM project_channels WHERE id = :id")
void delete(@BindBean ProjectChannelTable projectChannelTable);
@SqlQuery("SELECT * FROM project_channels WHERE project_id = :projectId")
List<ProjectChannelTable> getProjectChannels(long projectId);

View File

@ -35,16 +35,17 @@ public class ChannelService extends HangarService {
}
if (existingChannels.stream().anyMatch(ch -> ch.getColor() == color)) {
throw new HangarApiException(HttpStatus.BAD_REQUEST, "channel.modal.error.duplicateColor");
throw new HangarApiException(HttpStatus.CONFLICT, "channel.modal.error.duplicateColor");
}
if (existingChannels.stream().anyMatch(ch -> ch.getName().equalsIgnoreCase(name))) {
throw new HangarApiException(HttpStatus.BAD_REQUEST, "channel.modal.error.duplicateName");
throw new HangarApiException(HttpStatus.CONFLICT, "channel.modal.error.duplicateName");
}
}
public ProjectChannelTable createProjectChannel(String name, Color color, long projectId, boolean nonReviewed) {
validateChannel(name, color, projectId, nonReviewed, projectChannelsDAO.getProjectChannels(projectId));
// TODO user action logging
return projectChannelsDAO.insert(new ProjectChannelTable(name, color, projectId, nonReviewed));
}
@ -58,6 +59,20 @@ public class ChannelService extends HangarService {
projectChannelTable.setColor(color);
projectChannelTable.setNonReviewed(nonReviewed);
projectChannelsDAO.update(projectChannelTable);
// TODO user action logging
}
public void deleteProjectChannel(long projectId, long channelId) {
HangarChannel hangarChannel = hangarProjectsDAO.getHangarChannel(channelId);
if (hangarChannel == null) {
throw new HangarApiException(HttpStatus.NOT_FOUND);
}
if (hangarChannel.getVersionCount() != 0 || getProjectChannels(projectId).size() == 1) {
// Cannot delete channels with versions or if its the last channel
throw new HangarApiException(HttpStatus.BAD_REQUEST, "channel.modal.error.cannotDelete");
}
projectChannelsDAO.delete(hangarChannel);
// TODO user action logging
}
public List<HangarChannel> getProjectChannels(long projectId) {