mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2025-04-28 07:59:55 +03:00
feat(multi-delete): Add multi select delete for tags
This commit is contained in:
parent
ab37bcfcef
commit
63c310181b
3 changed files with 110 additions and 8 deletions
|
@ -395,10 +395,14 @@ select {
|
||||||
|
|
||||||
.remove-tag {
|
.remove-tag {
|
||||||
padding: 12px 5px;
|
padding: 12px 5px;
|
||||||
width: 30px;
|
width: 66px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.remove-tag.delete {
|
||||||
|
padding: 7px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
catalog material-card,
|
catalog material-card,
|
||||||
tag-history material-card {
|
tag-history material-card {
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
|
@ -470,3 +474,36 @@ catalog-element catalog-element.hide material-card {
|
||||||
margin-top: -50px;
|
margin-top: -50px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remove-image {
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
material-checkbox .label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
taglist material-checkbox {
|
||||||
|
margin: auto;
|
||||||
|
width: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
material-checkbox.indeterminate .checkbox .checkmark {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
material-checkbox.indeterminate .checkbox.checked .checkmark {
|
||||||
|
transform: rotate(90deg) scale(1);
|
||||||
|
-webkit-transform: rotate(90deg) scale(1);
|
||||||
|
-ms-transform: rotate(90deg) scale(1);
|
||||||
|
-moz-transform: rotate(90deg) scale(1);
|
||||||
|
-o-transform: rotate(90deg) scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
material-checkbox .checkbox {
|
||||||
|
border-color: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
material-checkbox .checkbox.checked {
|
||||||
|
background-color: #777;
|
||||||
|
}
|
|
@ -15,13 +15,21 @@ You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<remove-image>
|
<remove-image>
|
||||||
<material-button waves-center="true" rounded="true" waves-color="#ddd" title="This will delete the image.">
|
<material-button waves-center="true" rounded="true" waves-color="#ddd" title="This will delete the image." hide="{ opts.multiDelete }">
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
|
<material-checkbox show="{ opts.multiDelete }"></material-checkbox>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
|
this.on('update', function() {
|
||||||
|
if (!this.opts.multiDelete && this.tags['material-checkbox'].checked) {
|
||||||
|
this.tags['material-checkbox'].toggle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.on('mount', function() {
|
this.on('mount', function() {
|
||||||
this.tags['material-button'].root.onclick = function() {
|
this.delete = this.tags['material-button'].root.onclick = function(ignoreError) {
|
||||||
const name = self.opts.image.name;
|
const name = self.opts.image.name;
|
||||||
const tag = self.opts.image.tag;
|
const tag = self.opts.image.tag;
|
||||||
const oReq = new Http();
|
const oReq = new Http();
|
||||||
|
@ -39,7 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
registryUI.taglist.display()
|
registryUI.taglist.display()
|
||||||
registryUI.snackbar('Deleting ' + name + ':' + tag + ' image. Run `registry garbage-collect config.yml` on your registry');
|
registryUI.snackbar('Deleting ' + name + ':' + tag + ' image. Run `registry garbage-collect config.yml` on your registry');
|
||||||
} else if (this.status == 404) {
|
} else if (this.status == 404) {
|
||||||
registryUI.errorSnackbar('Digest not found');
|
ignoreError || registryUI.errorSnackbar('Digest not found');
|
||||||
} else {
|
} else {
|
||||||
registryUI.snackbar(this.responseText);
|
registryUI.snackbar(this.responseText);
|
||||||
}
|
}
|
||||||
|
@ -60,6 +68,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
oReq.setRequestHeader('Accept', 'application/vnd.docker.distribution.manifest.v2+json');
|
oReq.setRequestHeader('Accept', 'application/vnd.docker.distribution.manifest.v2+json');
|
||||||
oReq.send();
|
oReq.send();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.tags['material-checkbox'].on('toggle', function() {
|
||||||
|
registryUI.taglist.instance.trigger('toggle-remove-image', this.checked);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</remove-image>
|
</remove-image>
|
||||||
|
|
|
@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<taglist>
|
<taglist>
|
||||||
<!-- Begin of tag -->
|
<!-- Begin of tag -->
|
||||||
<material-card ref="taglist-tag" class="taglist">
|
<material-card ref="taglist-tag" class="taglist" multi-delete={ this.multiDelete }>
|
||||||
<div class="material-card-title-action">
|
<div class="material-card-title-action">
|
||||||
<material-button waves-center="true" rounded="true" waves-color="#ddd" onclick="registryUI.home();">
|
<material-button waves-center="true" rounded="true" waves-color="#ddd" onclick="registryUI.home();">
|
||||||
<i class="material-icons">arrow_back</i>
|
<i class="material-icons">arrow_back</i>
|
||||||
|
@ -42,7 +42,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
onclick="registryUI.taglist.reverse();">Tag
|
onclick="registryUI.taglist.reverse();">Tag
|
||||||
</th>
|
</th>
|
||||||
<th class="show-tag-history">History</th>
|
<th class="show-tag-history">History</th>
|
||||||
<th class="remove-tag" show="{ registryUI.isImageRemoveActivated }"></th>
|
<th class={ 'remove-tag': true, delete: this.parent.toDelete > 0 } show="{ registryUI.isImageRemoveActivated }"><material-checkbox ref="remove-tag-checkbox" class="indeterminate" show={ this.toDelete === 0}></material-checkbox>
|
||||||
|
<material-button waves-center="true" rounded="true" waves-color="#ddd" title="This will delete selected images." onclick={ registryUI.taglist.bulkDelete } show={ this.toDelete > 0 }>
|
||||||
|
<i class="material-icons">delete</i>
|
||||||
|
</material-button></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -64,14 +67,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<tag-history-button image={ image }/>
|
<tag-history-button image={ image }/>
|
||||||
</td>
|
</td>
|
||||||
<td show="{ registryUI.isImageRemoveActivated }">
|
<td show="{ registryUI.isImageRemoveActivated }">
|
||||||
<remove-image image={ image }/>
|
<remove-image multi-delete={ this.opts.multiDelete } image={ image }/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</material-card>
|
</material-card>
|
||||||
<script>
|
<script>
|
||||||
registryUI.taglist.instance = this;
|
var self = registryUI.taglist.instance = this;
|
||||||
|
|
||||||
|
this.multiDelete = false;
|
||||||
|
this.toDelete = 0;
|
||||||
|
|
||||||
|
this.on('delete', function() {
|
||||||
|
if (!registryUI.isImageRemoveActivated || !this.multiDelete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.on('multi-delete', function() {
|
||||||
|
if (!registryUI.isImageRemoveActivated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.multiDelete = !this.multiDelete;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.on('toggle-remove-image', function(checked) {
|
||||||
|
if (checked) {
|
||||||
|
this.toDelete++;
|
||||||
|
} else {
|
||||||
|
this.toDelete--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.toDelete <= 1) {
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
registryUI.taglist.bulkDelete = function() {
|
||||||
|
if (self.multiDelete && self.toDelete > 0) {
|
||||||
|
var images = self.refs['taglist-tag'].tags['remove-image'];
|
||||||
|
if (!(images instanceof Array)) {
|
||||||
|
images = [images];
|
||||||
|
}
|
||||||
|
images.filter(function(img) {
|
||||||
|
return img.tags['material-checkbox'].checked;
|
||||||
|
}).forEach(function(img) {
|
||||||
|
img.delete(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.on('mount', function() {
|
||||||
|
this.tags['material-card'].refs['remove-tag-checkbox'].on('toggle', function() {
|
||||||
|
registryUI.taglist.instance.multiDelete = this.checked;
|
||||||
|
registryUI.taglist.instance.update();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
registryUI.taglist.display = function() {
|
registryUI.taglist.display = function() {
|
||||||
registryUI.taglist.tags = [];
|
registryUI.taglist.tags = [];
|
||||||
if (route.routeName == 'taglist') {
|
if (route.routeName == 'taglist') {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue