Compare commits

...

9 Commits
1.1.2 ... 1.2.1

Author SHA1 Message Date
Joxit
cec469ab67 Update project page/README and example issue-75; rebuild project 2019-04-27 22:04:06 +02:00
Joxit
34200c1114 Release v1.2.1: Add multi-select shortcut 2019-04-25 00:11:41 +02:00
Joxit
67c6cb1bee feat(multi-select): Multi-select delete with select all 2019-04-25 00:05:29 +02:00
Joxit
021cddfef7 Fix canonical URL in _config.yml 2019-04-23 16:28:33 +02:00
Joxit
c01b440ff2 Release v1.2.0: Add multi-delete & demo canonical URL update 2019-04-23 08:06:41 +02:00
Joxit
63c310181b feat(multi-delete): Add multi select delete for tags 2019-04-23 08:04:38 +02:00
Vladimir Kozyrev
ab37bcfcef fix docker network name 2019-04-16 13:58:03 +02:00
Joxit
8e539be6ba Add quick example for issue #20
fixes: #20
2019-04-16 12:21:39 +02:00
Joxit
5b0ffc8eab Add quick exemple for issue #75 2019-04-15 20:30:50 +02:00
22 changed files with 389 additions and 48 deletions

3
.gitignore vendored
View File

@@ -2,4 +2,5 @@
node_modules
package-lock.json
registry-data
.idea
.idea
_site

View File

@@ -1,37 +1,47 @@
---
title: Project Page
---
# Docker Registry UI
## Overview
This project aims to provide a user interface for your private docker registry v2.
There is no default registry on this UI, you should add your own with the UI.
This project aims to provide a simple and complete user interface for your private docker registry.
You have the choice between two versions, the **standard interface** and the **static interface**.
In the **standard interface**, there is no default registry, you need to add your own within the UI.
You can manage more than one registry server.
All registries will be stored in the [local storage](https://en.wikipedia.org/wiki/Web_storage#Local_and_session_storage) of your browser.
All registries will be stored in the [local storage](https://en.wikipedia.org/wiki/Web_storage#Local_and_session_storage) of your browser. No configuration is needed when you launch the UI.
In the **static interface**, it will connect to a single registry and will not change. The configuration is done at the start of the interface, when you use the docker images whose tags contain the `static` keyword.
This web user interface uses [Riot](https://github.com/Riot/riot) the react-like user interface micro-library and [riot-mui](https://github.com/kysonic/riot-mui) components.
## [GitHub Page](https://joxit.dev/docker-registry-ui) and [Live Demo](https://joxit.dev/docker-registry-ui/demo/)
## [Project Page](https://joxit.dev/docker-registry-ui) and [Live Demo](https://joxit.dev/docker-registry-ui/demo/)
![preview](https://raw.github.com/Joxit/docker-registry-ui/master/docker-registry-ui.gif "Preview of Docker Registry UI")
## Features
- List all your repositories/images.
- List all tags for a repository/image
- Sort the tag list
- One interface for many registries
- Use a secured docker registry
- Share your docker registry with query parameter `url` (e.g. `https://joxit.dev/docker-registry-ui/demo?url=https://registry.example.com`)
- Use `joxit/docker-registry-ui:static` as reverse proxy to your docker registry (This will avoid CORS).
- Display image size (see #30)
- Add Title when using REGISTRY_URL (see #28)
- Alpine and Debian based images with supports for arm32v7 and arm64v8
- Copy `docker pull` command to clipbloard
- Show sha256 for specific tag (hover image tag)
- Display image creation date (see #49)
- Display image history (see #58)
- Display image/tag count
- Image aggregation (see #56)
- Customise docker pull command on static registry UI (see #71)
- List all tags for a image.
- Sort the tag list with number compatibility (see [#46](https://github.com/Joxit/docker-registry-ui/pull/46)).
- Use a secured docker registry.
- Display image size (see [#30](https://github.com/Joxit/docker-registry-ui/issues/30)).
- Multi arch supports, Alpine and Debian based images with supports for arm32v7 and arm64v8.
- Copy `docker pull` command to clipboard (see [#42](https://github.com/Joxit/docker-registry-ui/issues/42)).
- Show sha256 for specific tag (hover image tag).
- Display image creation date (see [#49](https://github.com/Joxit/docker-registry-ui/issues/49))
- Display image history (see [#58](https://github.com/Joxit/docker-registry-ui/pull/58) & [#61](https://github.com/Joxit/docker-registry-ui/pull/61)).
- Image aggregation (see [#56](https://github.com/Joxit/docker-registry-ui/issues/56)).
- Display image/tag count (see [#56 issue comment](https://github.com/Joxit/docker-registry-ui/issues/56#issuecomment-449246524)).
- Select multiple tags to delete (see [#29](https://github.com/Joxit/docker-registry-ui/issues/29)).
- Select all tags with ALT + Click to delete (see [#80](https://github.com/Joxit/docker-registry-ui/issues/80)).
- One interface for many registries **standard interface**.
- Share your docker registry with query parameter `url` (e.g. `https://joxit.dev/docker-registry-ui/demo?url=https://registry.example.com`) **standard interface**.
- Use `joxit/docker-registry-ui:static` as reverse proxy (with `REGISTRY_URL` environment variable) to your docker registry (This will avoid CORS) **static interface**.
- Add Title when using `REGISTRY_URL` (see [#28](https://github.com/Joxit/docker-registry-ui/issues/28)) **static interface**.
- Customise docker pull command on static registry UI (see [#71](https://github.com/Joxit/docker-registry-ui/issues/71)) **static interface**.
## Getting Started
@@ -102,7 +112,7 @@ To run the docker and see the website on your 80 port, try this:
docker run -d -p 80:80 joxit/docker-registry-ui
```
#### Run the static docker
#### Run the static interface
Some env options are available for use this interface for only one server.
@@ -119,7 +129,7 @@ docker run -d -p 80:80 -e URL=http://127.0.0.1:5000 -e DELETE_IMAGES=true joxit/
```
Example with `REGISTRY_URL`, this will add a proxy to your registry.
Your registry will be accessible here : `http://127.0.0.1/v2`, this will avoid CORS errors (see #25).
Your registry will be accessible here : `http://127.0.0.1/v2`, this will avoid CORS errors (see [#25](https://github.com/Joxit/docker-registry-ui/issues/25#issuecomment-360522487)).
Be careful, `joxit/docker-registry-ui` and `registry:2` will communicate, both containers should be in the same network or use your private IP.
```sh
@@ -198,3 +208,12 @@ auth:
realm: basic-realm
path: /etc/docker/registry/htpasswd
```
## All examples
- [Use docker-registry-ui as a proxy (use REGISTRY_URL)](https://github.com/Joxit/docker-registry-ui/tree/master/examples/ui-as-proxy)
- [Use docker-registry-ui as standalone (use URL)](https://github.com/Joxit/docker-registry-ui/tree/master/examples/ui-as-standalone)
- [Use docker-registry-ui with traefik](https://github.com/Joxit/docker-registry-ui/tree/master/examples/traefik)
- [Use docker-registry-ui with docker registry and Amazon s3 (#75)](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-75)
- [FIX revproxy to registry does not work when published under non-root url (#73)](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-73)
- [Use docker-registry-ui with HTTPS (#20)](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-20)

View File

@@ -1,6 +1,13 @@
title: Docker Registry v2 User Interface
title: Docker Registry User Interface
description: The simplest and most complete UI for your private registry!
url: https://joxit.dev/docker-registry-ui
google_analytics: UA-99119327-1
theme: jekyll-theme-cayman
author: Jones Magloire
twitter:
username: Joxit
username: Joxit
defaults:
- scope:
path: ""
values:
image: /screenshot.png

View File

@@ -24,15 +24,15 @@
<link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta property="og:locale" content="en_US" />
<meta name="description" content="This is the live demo for my project Docker Registry v2 web User Interface. Sources : https://github.com/Joxit/docker-registry-ui" />
<meta property="og:description" content="This is the live demo for my project Docker Registry v2 web User Interface. Sources : https://github.com/Joxit/docker-registry-ui" />
<link rel="canonical" href="http://joxit.dev/docker-registry-ui/demo/" />
<meta property="og:url" content="http://joxit.dev/docker-registry-ui/demo/" />
<meta property="og:site_name" content="Demo | Docker Registry UI" />
<meta name="description" content="This is the live demo for Docker Registry User Interface. Try it now! Sources : https://github.com/Joxit/docker-registry-ui" />
<meta property="og:description" content="This is the live demo for Docker Registry User Interface. Try it now! Sources : https://github.com/Joxit/docker-registry-ui" />
<link rel="canonical" href="https://joxit.dev/docker-registry-ui/demo/" />
<meta property="og:url" content="https://joxit.dev/docker-registry-ui/demo/" />
<meta property="og:site_name" content="Live Demo | Docker Registry User Interface" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@Joxit" />
<meta name="twitter:creator" content="@Jones Magloire" />
<title>Demo | Docker Registry UI</title>
<title>Live Demo | Docker Registry User Interface</title>
</head>
<body>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/style.css vendored

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
# Example for issue #20 (HTTPS supports)
This example will override the original nginx conf with one supporting HTTPS. You will need to rewrite all the project configuration (replaces `proxy_pass` with our value).
Generating a self signed certificate:
```
openssl req -newkey rsa:2048 -nodes -keyout nginx/privkey.pem -x509 -days 3650 -out nginx/fullchain.pem
```
The UI will be available here : https://localhost

View File

@@ -0,0 +1,27 @@
version: '2.0'
services:
registry:
image: registry:2.6.2
volumes:
- ./registry-data:/var/lib/registry
networks:
- registry-ui-net
ui:
image: joxit/docker-registry-ui:static
environment:
- REGISTRY_TITLE=My Private Docker Registry
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
- ./nginx/fullchain.pem:/etc/nginx/certs/fullchain.pem
- ./nginx/privkey.pem:/etc/nginx/certs/privkey.pem
ports:
- 80:80
- 443:443
depends_on:
- registry
networks:
- registry-ui-net
networks:
registry-ui-net:

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDYDCCAkigAwIBAgIJAKNtVPbuycx+MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTkwNDE2MDk1NzEzWhcNMjkwNDEzMDk1NzEzWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuykmuGBPiNDWzxmqK7BQgJqDLWbAsf4769sI2gSMR0C6qd6WV6JJ+Rf+
y1auT2fA38cvJUjdPBEQCTxpE3Ce3e9nXYTITzze6OUCwewbdR/Cm+dHyR+M2YNP
SQrZI6p4NE1TwCHc0LVWfblAaWiylFPeWlFCVSg5hqKAkRh9PEcWBdN5vim3/8sC
16YmXWCERGPdFKYBN52ERJ+9h51ktMdns0LJVn+DLVSNWsiH76IMulHU64d9nZoL
kVhxohiOeP2ZuV7E+9RYDlaKObohclPz3RoOXUbr3zjjna+dqxI6mxCw5qms26RL
eBcQQA/EoqaAv+y+jCKqbCCcEgy27QIDAQABo1MwUTAdBgNVHQ4EFgQUDKyOzsPn
Tc6ZTTdnt8U59/j+3l8wHwYDVR0jBBgwFoAUDKyOzsPnTc6ZTTdnt8U59/j+3l8w
DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAmqHfSjO58FoJWJUM
2i0rcql0Y24XjZ92RdBQGLkvAhi+QxWBXNKibvpen2miv3fAeYmiFtIHQCuOCqCj
SSdQwb91D5WR9s21PILEWsOd1H0v4ZVHX2Z5Qv5f6Hk1DiTG/sZmzUqog74TtCpG
4m56/JYd4Mkk9raiWT9RKVTVnSHjM8h2zIMio14Nil4zO67G68jp1K0C1AM9npsf
cvQ2+2XAOEcQ7e3nCF4ppA3HdnCm8qbr8DM12KTs+nkncps/7u+3C5vv5TxI+BEz
b5Cs+HbLwPAphYp0CSK+sXiCUMA//mUAcMeYKq2/V4wufJlZEpBxogdttW7J4KJm
Num0pw==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,24 @@
server {
listen 443 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
root /usr/share/nginx/html;
location /v2 {
# Do not allow connections from docker 1.5 and earlier
# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(.[0-9]-dev))|Go ).*$" ) {
return 404;
}
proxy_pass http://registry:5000;
}
}
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7KSa4YE+I0NbP
GaorsFCAmoMtZsCx/jvr2wjaBIxHQLqp3pZXokn5F/7LVq5PZ8Dfxy8lSN08ERAJ
PGkTcJ7d72ddhMhPPN7o5QLB7Bt1H8Kb50fJH4zZg09JCtkjqng0TVPAIdzQtVZ9
uUBpaLKUU95aUUJVKDmGooCRGH08RxYF03m+Kbf/ywLXpiZdYIREY90UpgE3nYRE
n72HnWS0x2ezQslWf4MtVI1ayIfvogy6UdTrh32dmguRWHGiGI54/Zm5XsT71FgO
Voo5uiFyU/PdGg5dRuvfOOOdr52rEjqbELDmqazbpEt4FxBAD8SipoC/7L6MIqps
IJwSDLbtAgMBAAECggEBAK7E+KFHXj22NkDiCGQPmrzcjA4DW4FalH3j5Vog0RVg
Pm6NqfpfU5BFdepPISqJCjRs/XtllSGYFU9ql/xNOCyqd+1+JsbHYqg74d1QKzut
0r5etEv9KDudQJZGiQmjD+hXJRPPCzHhg8iXCqzj1Y5o2sOgCb8XdtBgQoo7Qgbc
CG+3tytGPo33dotiFBUknrQRexTwgSWYXI89lI6fRSJlc8NyK7zp+mGbSopqGWHm
X6V8AI+XNuliIhTvOxGhw0maNEnds39SYHCYfLATjp9x6XVVp5mG7BJLkifC8Cob
IYQGfBwmEYbOTiNJ6oEgRZOZFPsLbqsPfPgTpHvIwUECgYEA7WfYek3DWkC7Ex3r
7hcZjBa8JMxPhgSMho/5F8zHGAf8MdEmXPYKi9tvhLeMJQwzzlN4RtX9zg0FJ5eL
tSgGHT/aRc2/9ZAvuG7gypNZlaAd+/SloYfKsGJQxFqLTfm288qyrRoOtBjhRMCI
lRmw5uYVV775cK741+lyD5xj/DkCgYEAydHb8mIt/IvCloVGzP8z4veIarEecYk3
UPw/wneZFZwGegGTsCwxox1uWVcO5CoNLhRo7622kZ6Mhsd83ySj8eQWpR1qoeMJ
8ti9c2FniZdtUwdFgu7GPgJq3DWTVQ0c0MTnyk/UbsfD/AKG0YK9T2sReteaPOUg
nohVutYZuFUCgYEAorXau7BSZKgaz3ZhfjQc0VO/rWTOWCcD/THt4i76gXDvm2Ei
bvI+ti42V3rJNZcQZqf0tm/x3Og1kTYfjZCZ6DAcNF1Y5D/nRPvRW2X0L0WnZ0j8
wCHmfE9V1c3MziuJBbv2DAfg7fRjaJCgy7fo88fb9uCv61gwuyKHh0WDjZkCgYB3
R89lLF3dm4TAjbjQxCyYgpBf7pr9o4nMFaphd2pE+Vhil7gAMb6Ml4J2zxuAAtKT
X4C917/FxR1tM048XF2BQ7uWjxJM5/EjVLJ0FSeqjJMStYOB5TnJwIgD6q5PYFad
lSMh0ZjOeMb+lUe1YD4fSDqmjfMc9pcW26E/sfa1mQKBgQDMRKH/R+yw6Nemu837
mwNVTiKtQoWS8jl8Gwox6o3cgrV/6szQaQz8oF9x829jFehYEMGYMX/8zPToyBCU
gRod6bcMmdLB8EQd7VI5L9/CeoZQmpVVZ1STNjUqscE/Gb98nCPNXTkVeAgtE1WS
AVhAAc+34wOxlAcjcXweBK69kg==
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,7 @@
# Example for issue #75
Run this command `docker-compose up -d`, then you can push your images (e.g localhost:5000/alpine).
Be careful, the docker registry is using status codes 307 for each requests, that means you must configure your s3 to accept same requests as your private registry (that means `DELETE`, `Access-Control-Allow-Origin` and others). To avoid this, we need the option `storage.redirect.disable: true`, with this you will use your registry credentials (if you are using it).
This s3 server allow all requests.

View File

@@ -0,0 +1,32 @@
version: '2.0'
services:
registry:
image: registry:2.7
volumes:
- ./registry-data:/var/lib/registry
- ./registry-config/config.yml:/etc/docker/registry/config.yml
depends_on:
- s3-server
network_mode: host
ui:
image: joxit/docker-registry-ui:static
ports:
- 80:80
environment:
- URL=http://127.0.0.1:5000
- DELETE_IMAGES=true
depends_on:
- registry
network_mode: host
s3-server:
image: minio/minio:RELEASE.2019-04-09T01-22-30Z
volumes:
- ./s3-server-cmd:/bin/s3-server-cmd:ro
environment:
- MINIO_ACCESS_KEY=accessKey1
- MINIO_SECRET_KEY=verySecretKey1
- MINIO_REGION=us-east-1
network_mode: host
entrypoint: /bin/s3-server-cmd

View File

@@ -0,0 +1,39 @@
version: 0.1
log:
level: debug
fields:
service: registry
storage:
delete:
enabled: true
cache:
blobdescriptor: inmemory
s3:
accesskey: accessKey1
secretkey: verySecretKey1
region: us-east-1
regionendpoint: http://127.0.0.1:9000
bucket: registry
encrypt: false
secure: false
v4auth: true
chunksize: 5242880
rootdirectory: /
redirect:
disable: true
http:
addr: 0.0.0.0:5000
headers:
X-Content-Type-Options: [nosniff]
Access-Control-Allow-Origin: ['http://127.0.0.1']
Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
Access-Control-Allow-Headers: ['Authorization']
Access-Control-Max-Age: [1728000]
Access-Control-Allow-Credentials: [true]
Access-Control-Expose-Headers: ['Docker-Content-Digest']
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3

View File

@@ -0,0 +1,6 @@
#!/bin/sh
set -e
mkdir -p /data/registry
minio server /data

View File

@@ -5,7 +5,7 @@ services:
volumes:
- ./registry-data:/var/lib/registry
networks:
- docker-registry-ui
- registry-ui-net
ui:
image: joxit/docker-registry-ui:static
@@ -17,7 +17,7 @@ services:
depends_on:
- registry
networks:
- docker-registry-ui
- registry-ui-net
networks:
registry-ui-net:
registry-ui-net:

1
index.md Symbolic link
View File

@@ -0,0 +1 @@
README.md

View File

@@ -1,6 +1,6 @@
{
"name": "docker-registry-ui",
"version": "1.1.2",
"version": "1.2.1",
"scripts": {
"build": "./node_modules/gulp/bin/gulp.js build"
},
@@ -14,8 +14,8 @@
"dependencies": {},
"devDependencies": {
"del": "^3.0.0",
"gulp": "^4.0",
"gulp-clean-css": "^4.0.0",
"gulp": "^4.0.1",
"gulp-clean-css": "^4.2.0",
"gulp-concat": "^2.6.0",
"gulp-filter": "^5.1.0",
"gulp-htmlmin": "^5.0.1",

View File

@@ -395,10 +395,14 @@ select {
.remove-tag {
padding: 12px 5px;
width: 30px;
width: 66px;
text-align: center;
}
.remove-tag.delete {
padding: 7px 5px;
}
catalog material-card,
tag-history material-card {
min-height: auto;
@@ -469,4 +473,37 @@ catalog-element catalog-element.showing material-card,
catalog-element catalog-element.hide material-card {
margin-top: -50px;
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;
}

View File

@@ -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/>.
-->
<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>
</material-button>
<material-checkbox show="{ opts.multiDelete }" title="Select this tag to delete it."></material-checkbox>
<script type="text/javascript">
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.tags['material-button'].root.onclick = function() {
this.delete = this.tags['material-button'].root.onclick = function(ignoreError) {
const name = self.opts.image.name;
const tag = self.opts.image.tag;
const oReq = new Http();
@@ -39,7 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
registryUI.taglist.display()
registryUI.snackbar('Deleting ' + name + ':' + tag + ' image. Run `registry garbage-collect config.yml` on your registry');
} else if (this.status == 404) {
registryUI.errorSnackbar('Digest not found');
ignoreError || registryUI.errorSnackbar('Digest not found');
} else {
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.send();
};
this.tags['material-checkbox'].on('toggle', function() {
registryUI.taglist.instance.trigger('toggle-remove-image', this.checked);
});
});
</script>
</remove-image>

View File

@@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<taglist>
<!-- 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">
<material-button waves-center="true" rounded="true" waves-color="#ddd" onclick="registryUI.home();">
<i class="material-icons">arrow_back</i>
@@ -42,7 +42,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
onclick="registryUI.taglist.reverse();">Tag
</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} title="Toggle multi-delete. Alt+Click to select all tags."></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>
</thead>
<tbody>
@@ -64,14 +68,79 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<tag-history-button image={ image }/>
</td>
<td show="{ registryUI.isImageRemoveActivated }">
<remove-image image={ image }/>
<remove-image multi-delete={ this.opts.multiDelete } image={ image }/>
</td>
</tr>
</tbody>
</table>
</material-card>
<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();
}
});
this._getRemoveImageTags = function() {
var images = self.refs['taglist-tag'].tags['remove-image'];
if (!(images instanceof Array)) {
images = [images];
}
return images;
};
registryUI.taglist.bulkDelete = function() {
if (self.multiDelete && self.toDelete > 0) {
self._getRemoveImageTags().filter(function(img) {
return img.tags['material-checkbox'].checked;
}).forEach(function(img) {
img.delete(true);
});
}
};
this.on('mount', function() {
var toggle = this.tags['material-card'].refs['remove-tag-checkbox'].toggle;
this.tags['material-card'].refs['remove-tag-checkbox'].toggle = function(e) {
if (e.altKey) {
self._getRemoveImageTags()
.filter(function(img) { return !img.tags['material-checkbox'].checked; })
.forEach(function(img) { img.tags['material-checkbox'].toggle() });
} else {
toggle();
}
};
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.tags = [];
if (route.routeName == 'taglist') {