mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2025-04-27 07:29:54 +03:00
feat: expose some custom labels
This commit is contained in:
parent
19e72e4a5f
commit
ba6d817b41
7 changed files with 182 additions and 129 deletions
|
@ -100,6 +100,7 @@ Some env options are available for use this interface for **only one server**.
|
||||||
- `DEFAULT_REGISTRIES`: List of comma separated registry URLs (e.g `http://registry.example.com,http://registry:5000`), available only when `SINGLE_REGISTRY=false`. (default: ` `).
|
- `DEFAULT_REGISTRIES`: List of comma separated registry URLs (e.g `http://registry.example.com,http://registry:5000`), available only when `SINGLE_REGISTRY=false`. (default: ` `).
|
||||||
- `READ_ONLY_REGISTRIES`: Desactivate dialog for remove and add new registries, available only when `SINGLE_REGISTRY=false`. (default: `false`).
|
- `READ_ONLY_REGISTRIES`: Desactivate dialog for remove and add new registries, available only when `SINGLE_REGISTRY=false`. (default: `false`).
|
||||||
- `SHOW_CATALOG_NB_TAGS`: Show number of tags per images on catalog page. This will produce + nb images requests, not recommended on large registries. (default: `false`).
|
- `SHOW_CATALOG_NB_TAGS`: Show number of tags per images on catalog page. This will produce + nb images requests, not recommended on large registries. (default: `false`).
|
||||||
|
- `HISTORY_CUSTOM_LABELS`: Expose custom labels in history page, custom labels will be processed like maintainer label.
|
||||||
|
|
||||||
There are some examples with [docker-compose](https://docs.docker.com/compose/) and docker-registry-ui as proxy [here](https://github.com/Joxit/docker-registry-ui/tree/main/examples/ui-as-proxy/) or docker-registry-ui as standalone [here](https://github.com/Joxit/docker-registry-ui/tree/main/examples/ui-as-standalone/).
|
There are some examples with [docker-compose](https://docs.docker.com/compose/) and docker-registry-ui as proxy [here](https://github.com/Joxit/docker-registry-ui/tree/main/examples/ui-as-proxy/) or docker-registry-ui as standalone [here](https://github.com/Joxit/docker-registry-ui/tree/main/examples/ui-as-standalone/).
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ sed -i "s~\${SHOW_CONTENT_DIGEST}~${SHOW_CONTENT_DIGEST}~" index.html
|
||||||
sed -i "s~\${DEFAULT_REGISTRIES}~${DEFAULT_REGISTRIES}~" index.html
|
sed -i "s~\${DEFAULT_REGISTRIES}~${DEFAULT_REGISTRIES}~" index.html
|
||||||
sed -i "s~\${READ_ONLY_REGISTRIES}~${READ_ONLY_REGISTRIES}~" index.html
|
sed -i "s~\${READ_ONLY_REGISTRIES}~${READ_ONLY_REGISTRIES}~" index.html
|
||||||
sed -i "s~\${SHOW_CATALOG_NB_TAGS}~${SHOW_CATALOG_NB_TAGS}~" index.html
|
sed -i "s~\${SHOW_CATALOG_NB_TAGS}~${SHOW_CATALOG_NB_TAGS}~" index.html
|
||||||
|
sed -i "s~\${HISTORY_CUSTOM_LABELS}~${HISTORY_CUSTOM_LABELS}~" index.html
|
||||||
|
|
||||||
if [ -z "${DELETE_IMAGES}" ] || [ "${DELETE_IMAGES}" = false ] ; then
|
if [ -z "${DELETE_IMAGES}" ] || [ "${DELETE_IMAGES}" = false ] ; then
|
||||||
sed -i "s/\${DELETE_IMAGES}/false/" index.html
|
sed -i "s/\${DELETE_IMAGES}/false/" index.html
|
||||||
|
|
|
@ -42,7 +42,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<tag-history registry-url="{ state.registryUrl }" registry-name="{ state.name }" pull-url="{ state.pullUrl }"
|
<tag-history registry-url="{ state.registryUrl }" registry-name="{ state.name }" pull-url="{ state.pullUrl }"
|
||||||
image="{ router.getTagHistoryImage() }" tag="{ router.getTagHistoryTag() }"
|
image="{ router.getTagHistoryImage() }" tag="{ router.getTagHistoryTag() }"
|
||||||
is-image-remove-activated="{ truthy(props.isImageRemoveActivated) }" on-notify="{ notifySnackbar }"
|
is-image-remove-activated="{ truthy(props.isImageRemoveActivated) }" on-notify="{ notifySnackbar }"
|
||||||
on-authentication="{ onAuthentication }"></tag-history>
|
on-authentication="{ onAuthentication }" history-custom-labels="{ stringToArray(props.historyCustomLabels) }"></tag-history>
|
||||||
</route>
|
</route>
|
||||||
</router>
|
</router>
|
||||||
<registry-authentication realm="{ state.realm }" scope="{ state.scope }" service="{ state.service }"
|
<registry-authentication realm="{ state.realm }" scope="{ state.scope }" service="{ state.service }"
|
||||||
|
@ -80,7 +80,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
stripHttps,
|
stripHttps,
|
||||||
getRegistryServers,
|
getRegistryServers,
|
||||||
setRegistryServers,
|
setRegistryServers,
|
||||||
truthy
|
truthy,
|
||||||
|
stringToArray
|
||||||
} from '../scripts/utils';
|
} from '../scripts/utils';
|
||||||
import router from '../scripts/router';
|
import router from '../scripts/router';
|
||||||
|
|
||||||
|
@ -175,7 +176,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
baseRoute: '([^#]*?)/(\\?[^#]*?)?(#!)?(/?)',
|
baseRoute: '([^#]*?)/(\\?[^#]*?)?(#!)?(/?)',
|
||||||
router,
|
router,
|
||||||
version,
|
version,
|
||||||
truthy
|
truthy,
|
||||||
|
stringToArray
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</docker-registry-ui>
|
</docker-registry-ui>
|
|
@ -15,17 +15,16 @@ 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/>.
|
||||||
-->
|
-->
|
||||||
<tag-history-element class="{ state.key }">
|
<tag-history-element class="{ state.key }">
|
||||||
<div class="headline"><i class="material-icons">{ state.icon }</i>
|
<div class="headline">
|
||||||
|
<i class="material-icons">{ state.icon }</i>
|
||||||
<p>{ state.name }</p>
|
<p>{ state.name }</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="value" if="{ state.value }"> { state.value }</div>
|
<div class="value" if="{ state.value }">{ state.value }</div>
|
||||||
<div class="values value" each="{ value in state.values }" if="{ state.values }"> { value }</div>
|
<div class="values value" each="{ value in state.values }" if="{ state.values }">{ value }</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { getHistoryIcon } from '../../scripts/utils';
|
||||||
getHistoryIcon
|
|
||||||
} from '../../scripts/utils';
|
|
||||||
export default {
|
export default {
|
||||||
onBeforeStart(props, state) {
|
onBeforeStart(props, state) {
|
||||||
state.key = props.entry.key;
|
state.key = props.entry.key;
|
||||||
|
@ -48,14 +47,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
return name;
|
return name;
|
||||||
} else if (name === 'os') {
|
} else if (name === 'os') {
|
||||||
return 'OS';
|
return 'OS';
|
||||||
|
} else if (name.startsWith('custom-label-')) {
|
||||||
|
name = name.replace('custom-label-', '');
|
||||||
}
|
}
|
||||||
return name.replace(/([a-z])([A-Z])/g, '$1 $2')
|
return name
|
||||||
.replace('_', ' ')
|
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
||||||
|
.replace(/[_-]/g, ' ')
|
||||||
.split(' ')
|
.split(' ')
|
||||||
.map(word => `${word.charAt(0).toUpperCase()}${word.slice(1)}`)
|
.map((word) => `${word.charAt(0).toUpperCase()}${word.slice(1)}`)
|
||||||
.join(' ');
|
.join(' ');
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
:host.Labels .value,
|
:host.Labels .value,
|
||||||
|
@ -70,7 +72,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
:host.docker_version .headline .material-icons {
|
:host.docker_version .headline .material-icons {
|
||||||
background-size: 24px auto;
|
background-size: 24px auto;
|
||||||
background-image: url("images/docker-logo.svg");
|
background-image: url('images/docker-logo.svg');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,33 +20,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<material-button waves-center="true" rounded="true" waves-color="#ddd" onClick="{ toTaglist }">
|
<material-button waves-center="true" rounded="true" waves-color="#ddd" onClick="{ toTaglist }">
|
||||||
<i class="material-icons">arrow_back</i>
|
<i class="material-icons">arrow_back</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
<h2>
|
<h2>History of { props.image }:{ props.tag } <i class="material-icons">history</i></h2>
|
||||||
History of { props.image }:{ props.tag } <i class="material-icons">history</i>
|
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
</material-card>
|
</material-card>
|
||||||
<div if="{ !state.loadend }" class="spinner-wrapper">
|
<div if="{ !state.loadend }" class="spinner-wrapper">
|
||||||
<material-spinner />
|
<material-spinner></material-spinner>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<material-tabs if="{ state.archs && state.loadend }" useLine="{ true }" tabs="{ state.archs }"
|
<material-tabs
|
||||||
onTabChanged="{ onTabChanged }" />
|
if="{ state.archs && state.loadend }"
|
||||||
|
useLine="{ true }"
|
||||||
|
tabs="{ state.archs }"
|
||||||
|
onTabChanged="{ onTabChanged }"
|
||||||
|
></material-tabs>
|
||||||
|
|
||||||
<material-card each="{ element in state.elements }" class="tag-history-element">
|
<material-card each="{ element in state.elements }" class="tag-history-element">
|
||||||
<tag-history-element each="{ entry in element }" if="{ entry.value && entry.value.length > 0}" entry="{ entry }" />
|
<tag-history-element
|
||||||
|
each="{ entry in element }"
|
||||||
|
if="{ entry.value && entry.value.length > 0}"
|
||||||
|
entry="{ entry }"
|
||||||
|
></tag-history-element>
|
||||||
</material-card>
|
</material-card>
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { DockerImage } from '../../scripts/docker-image';
|
||||||
DockerImage
|
import { bytesToSize } from '../../scripts/utils';
|
||||||
} from '../../scripts/docker-image';
|
|
||||||
import {
|
|
||||||
bytesToSize
|
|
||||||
} from '../../scripts/utils';
|
|
||||||
import router from '../../scripts/router';
|
import router from '../../scripts/router';
|
||||||
import TagHistoryElement from './tag-history-element.riot'
|
import TagHistoryElement from './tag-history-element.riot';
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
TagHistoryElement
|
TagHistoryElement,
|
||||||
},
|
},
|
||||||
onBeforeMount(props, state) {
|
onBeforeMount(props, state) {
|
||||||
state.elements = [];
|
state.elements = [];
|
||||||
|
@ -54,9 +56,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
list: true,
|
list: true,
|
||||||
registryUrl: props.registryUrl,
|
registryUrl: props.registryUrl,
|
||||||
onNotify: props.onNotify,
|
onNotify: props.onNotify,
|
||||||
onAuthentication: props.onAuthentication
|
onAuthentication: props.onAuthentication,
|
||||||
});
|
});
|
||||||
state.image.fillInfo()
|
state.image.fillInfo();
|
||||||
},
|
},
|
||||||
onMounted(props, state) {
|
onMounted(props, state) {
|
||||||
state.image.on('blobs', this.processBlobs);
|
state.image.on('blobs', this.processBlobs);
|
||||||
|
@ -64,16 +66,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
},
|
},
|
||||||
onTabChanged(arch, idx) {
|
onTabChanged(arch, idx) {
|
||||||
const state = this.state;
|
const state = this.state;
|
||||||
const {
|
const { registryUrl, onNotify } = this.props;
|
||||||
registryUrl,
|
state.elements = [];
|
||||||
onNotify
|
state.image.variants[idx] =
|
||||||
} = this.props;
|
state.image.variants[idx] ||
|
||||||
state.elements = []
|
|
||||||
state.image.variants[idx] = state.image.variants[idx] ||
|
|
||||||
new DockerImage(this.props.image, arch.digest, {
|
new DockerImage(this.props.image, arch.digest, {
|
||||||
list: false,
|
list: false,
|
||||||
registryUrl,
|
registryUrl,
|
||||||
onNotify
|
onNotify,
|
||||||
});
|
});
|
||||||
if (state.image.variants[idx].blobs) {
|
if (state.image.variants[idx].blobs) {
|
||||||
return this.processBlobs(state.image.variants[idx].blobs);
|
return this.processBlobs(state.image.variants[idx].blobs);
|
||||||
|
@ -83,6 +83,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
},
|
},
|
||||||
processBlobs(blobs) {
|
processBlobs(blobs) {
|
||||||
const state = this.state;
|
const state = this.state;
|
||||||
|
const { historyCustomLabels } = this.props;
|
||||||
|
|
||||||
function exec(elt) {
|
function exec(elt) {
|
||||||
const guiElements = [];
|
const guiElements = [];
|
||||||
|
@ -90,8 +91,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
if (elt.hasOwnProperty(attribute) && attribute != 'empty_layer') {
|
if (elt.hasOwnProperty(attribute) && attribute != 'empty_layer') {
|
||||||
const value = elt[attribute];
|
const value = elt[attribute];
|
||||||
const guiElement = {
|
const guiElement = {
|
||||||
"key": attribute,
|
'key': attribute,
|
||||||
"value": modifySpecificAttributeTypes(attribute, value)
|
'value': modifySpecificAttributeTypes(attribute, value),
|
||||||
};
|
};
|
||||||
guiElements.push(guiElement);
|
guiElements.push(guiElement);
|
||||||
}
|
}
|
||||||
|
@ -99,32 +100,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
return guiElements.sort(eltSort);
|
return guiElements.sort(eltSort);
|
||||||
}
|
}
|
||||||
const elements = new Array(blobs.history.length + 1);
|
const elements = new Array(blobs.history.length + 1);
|
||||||
elements[0] = exec(getConfig(blobs));
|
elements[0] = exec(getConfig(blobs, { historyCustomLabels }));
|
||||||
blobs.history.forEach(function (elt, i) {
|
blobs.history.forEach(function (elt, i) {
|
||||||
elements[blobs.history.length - i] = exec(elt)
|
elements[blobs.history.length - i] = exec(elt);
|
||||||
});
|
});
|
||||||
this.update({
|
this.update({
|
||||||
elements,
|
elements,
|
||||||
loadend: true
|
loadend: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
multiArchList(manifests) {
|
multiArchList(manifests) {
|
||||||
manifests = manifests.manifests || manifests;
|
manifests = manifests.manifests || manifests;
|
||||||
const archs = manifests.map(function (manifest) {
|
const archs = manifests.map(function (manifest) {
|
||||||
return {
|
return {
|
||||||
title: manifest.platform.os + '/' + manifest.platform.architecture + (manifest.platform.variant ?
|
title:
|
||||||
manifest.platform.variant : ''),
|
manifest.platform.os +
|
||||||
digest: manifest.digest
|
'/' +
|
||||||
}
|
manifest.platform.architecture +
|
||||||
|
(manifest.platform.variant ? manifest.platform.variant : ''),
|
||||||
|
digest: manifest.digest,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
this.update({
|
this.update({
|
||||||
archs
|
archs,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
toTaglist() {
|
toTaglist() {
|
||||||
router.taglist(this.props.image);
|
router.taglist(this.props.image);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
const eltIdx = function (e) {
|
const eltIdx = function (e) {
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case 'created':
|
case 'created':
|
||||||
|
@ -158,7 +162,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
return new Date(value).toLocaleString();
|
return new Date(value).toLocaleString();
|
||||||
case 'created_by':
|
case 'created_by':
|
||||||
const cmd = value.match(/\/bin\/sh *-c *#\(nop\) *([A-Z]+)/);
|
const cmd = value.match(/\/bin\/sh *-c *#\(nop\) *([A-Z]+)/);
|
||||||
return (cmd && cmd[1]) || 'RUN'
|
return (cmd && cmd[1]) || 'RUN';
|
||||||
case 'size':
|
case 'size':
|
||||||
return bytesToSize(value);
|
return bytesToSize(value);
|
||||||
case 'Entrypoint':
|
case 'Entrypoint':
|
||||||
|
@ -175,25 +179,46 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
return value || '';
|
return value || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const getConfig = function (blobs) {
|
const getConfig = function (blobs, { historyCustomLabels }) {
|
||||||
const res = ['architecture', 'User', 'created', 'docker_version', 'os', 'Cmd', 'Entrypoint', 'Env', 'Labels',
|
console.log(this);
|
||||||
'User', 'Volumes', 'WorkingDir', 'author', 'id', 'ExposedPorts'
|
const res = [
|
||||||
]
|
'architecture',
|
||||||
.reduce(function (acc, e) {
|
'User',
|
||||||
const value = blobs[e] || blobs.config[e];
|
'created',
|
||||||
if (value && e === 'architecture' && blobs.variant) {
|
'docker_version',
|
||||||
acc[e] = value + blobs.variant;
|
'os',
|
||||||
} else if (value) {
|
'Cmd',
|
||||||
acc[e] = value;
|
'Entrypoint',
|
||||||
}
|
'Env',
|
||||||
return acc;
|
'Labels',
|
||||||
}, {});
|
'User',
|
||||||
|
'Volumes',
|
||||||
|
'WorkingDir',
|
||||||
|
'author',
|
||||||
|
'id',
|
||||||
|
'ExposedPorts',
|
||||||
|
].reduce(function (acc, e) {
|
||||||
|
const value = blobs[e] || blobs.config[e];
|
||||||
|
if (value && e === 'architecture' && blobs.variant) {
|
||||||
|
acc[e] = value + blobs.variant;
|
||||||
|
} else if (value) {
|
||||||
|
acc[e] = value;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
if (!res.author && (res.Labels && res.Labels.maintainer)) {
|
if (!res.author && res.Labels && res.Labels.maintainer) {
|
||||||
res.author = blobs.config.Labels.maintainer;
|
res.author = blobs.config.Labels.maintainer;
|
||||||
delete res.Labels.maintainer;
|
delete res.Labels.maintainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
historyCustomLabels
|
||||||
|
.filter((label) => res.Labels[label])
|
||||||
|
.forEach((label) => {
|
||||||
|
res[`custom-label-${label}`] = res.Labels[label];
|
||||||
|
delete res.Labels[label];
|
||||||
|
});
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
131
src/index.html
131
src/index.html
|
@ -16,63 +16,78 @@
|
||||||
-->
|
-->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<!-- build:css docker-registry-ui.css -->
|
||||||
|
<link href="../node_modules/riot-mui/build/styles/riot-mui.min.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="style.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="material-icons.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="roboto.css" rel="stylesheet" type="text/css" />
|
||||||
|
<!-- endbuild -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta property="og:site_name" content="Docker Registry UI" />
|
||||||
|
<meta name="twitter:card" content="summary" />
|
||||||
|
<meta name="twitter:site" content="@Joxit" />
|
||||||
|
<meta name="twitter:creator" content="@Jones Magloire" />
|
||||||
|
<title>Docker Registry UI</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
<head>
|
<body>
|
||||||
<meta charset="UTF-8">
|
<!-- build:keep production -->
|
||||||
<!-- build:css docker-registry-ui.css -->
|
<docker-registry-ui
|
||||||
<link href="../node_modules/riot-mui/build/styles/riot-mui.min.css" rel="stylesheet" type="text/css">
|
registry-url="${REGISTRY_URL}"
|
||||||
<link href="style.css" rel="stylesheet" type="text/css">
|
name="${REGISTRY_TITLE}"
|
||||||
<link href="material-icons.css" rel="stylesheet" type="text/css">
|
pull-url="${PULL_URL}"
|
||||||
<link href="roboto.css" rel="stylesheet" type="text/css">
|
show-content-digest="${SHOW_CONTENT_DIGEST}"
|
||||||
<!-- endbuild -->
|
is-image-remove-activated="${DELETE_IMAGES}"
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
catalog-elements-limit="${CATALOG_ELEMENTS_LIMIT}"
|
||||||
<meta property="og:site_name" content="Docker Registry UI" />
|
single-registry="${SINGLE_REGISTRY}"
|
||||||
<meta name="twitter:card" content="summary" />
|
default-registries="${DEFAULT_REGISTRIES}"
|
||||||
<meta name="twitter:site" content="@Joxit" />
|
read-only-registries="${READ_ONLY_REGISTRIES}"
|
||||||
<meta name="twitter:creator" content="@Jones Magloire" />
|
show-catalog-nb-tags="${SHOW_CATALOG_NB_TAGS}"
|
||||||
<title>Docker Registry UI</title>
|
history-custom-labels="${HISTORY_CUSTOM_LABELS}"
|
||||||
</head>
|
>
|
||||||
|
</docker-registry-ui>
|
||||||
<body>
|
<!-- endbuild -->
|
||||||
<!-- build:keep production -->
|
<!-- build:keep developement -->
|
||||||
<docker-registry-ui registry-url="${REGISTRY_URL}" name="${REGISTRY_TITLE}" pull-url="${PULL_URL}"
|
<docker-registry-ui
|
||||||
show-content-digest="${SHOW_CONTENT_DIGEST}" is-image-remove-activated="${DELETE_IMAGES}"
|
registry-url=""
|
||||||
catalog-elements-limit="${CATALOG_ELEMENTS_LIMIT}" single-registry="${SINGLE_REGISTRY}"
|
name="Developement Registry"
|
||||||
default-registries="${DEFAULT_REGISTRIES}" read-only-registries="${READ_ONLY_REGISTRIES}"
|
pull-url=""
|
||||||
show-catalog-nb-tags="${SHOW_CATALOG_NB_TAGS}">
|
show-content-digest="true"
|
||||||
</docker-registry-ui>
|
is-image-remove-activated="true"
|
||||||
<!-- endbuild -->
|
catalog-elements-limit="1000"
|
||||||
<!-- build:keep developement -->
|
single-registry="false"
|
||||||
<docker-registry-ui registry-url="" name="Developement Registry" pull-url="" show-content-digest="true"
|
show-catalog-nb-tags="true"
|
||||||
is-image-remove-activated="true" catalog-elements-limit="1000" single-registry="false" show-catalog-nb-tags="true">
|
history-custom-labels="first_custom_labels,second_custom_labels"
|
||||||
</docker-registry-ui>
|
>
|
||||||
<!-- endbuild -->
|
</docker-registry-ui>
|
||||||
<!-- build:js docker-registry-ui.js -->
|
<!-- endbuild -->
|
||||||
<script src="../node_modules/riot/riot+compiler.min.js"></script>
|
<!-- build:js docker-registry-ui.js -->
|
||||||
<script src="../node_modules/riot-route/dist/route.js"></script>
|
<script src="../node_modules/riot/riot+compiler.min.js"></script>
|
||||||
<script src="../node_modules/riot-mui/build/js/riot-mui.js"></script>
|
<script src="../node_modules/riot-route/dist/route.js"></script>
|
||||||
<script src="tags/catalog.riot" type="riot/tag"></script>
|
<script src="../node_modules/riot-mui/build/js/riot-mui.js"></script>
|
||||||
<script src="tags/catalog-element.riot" type="riot/tag"></script>
|
<script src="tags/catalog.riot" type="riot/tag"></script>
|
||||||
<script src="tags/tag-history-button.riot" type="riot/tag"></script>
|
<script src="tags/catalog-element.riot" type="riot/tag"></script>
|
||||||
<script src="tags/tag-history.riot" type="riot/tag"></script>
|
<script src="tags/tag-history-button.riot" type="riot/tag"></script>
|
||||||
<script src="tags/tag-history-element.riot" type="riot/tag"></script>
|
<script src="tags/tag-history.riot" type="riot/tag"></script>
|
||||||
<script src="tags/taglist.riot" type="riot/tag"></script>
|
<script src="tags/tag-history-element.riot" type="riot/tag"></script>
|
||||||
<script src="tags/image-tag.riot" type="riot/tag"></script>
|
<script src="tags/taglist.riot" type="riot/tag"></script>
|
||||||
<script src="tags/remove-image.riot" type="riot/tag"></script>
|
<script src="tags/image-tag.riot" type="riot/tag"></script>
|
||||||
<script src="tags/copy-to-clipboard.riot" type="riot/tag"></script>
|
<script src="tags/remove-image.riot" type="riot/tag"></script>
|
||||||
<script src="tags/dialogs/add.riot" type="riot/tag"></script>
|
<script src="tags/copy-to-clipboard.riot" type="riot/tag"></script>
|
||||||
<script src="tags/dialogs/change.riot" type="riot/tag"></script>
|
<script src="tags/dialogs/add.riot" type="riot/tag"></script>
|
||||||
<script src="tags/dialogs/remove.riot" type="riot/tag"></script>
|
<script src="tags/dialogs/change.riot" type="riot/tag"></script>
|
||||||
<script src="tags/dialogs/menu.riot" type="riot/tag"></script>
|
<script src="tags/dialogs/remove.riot" type="riot/tag"></script>
|
||||||
<script src="tags/image-size.riot" type="riot/tag"></script>
|
<script src="tags/dialogs/menu.riot" type="riot/tag"></script>
|
||||||
<script src="tags/image-date.riot" type="riot/tag"></script>
|
<script src="tags/image-size.riot" type="riot/tag"></script>
|
||||||
<script src="tags/image-content-digest.riot" type="riot/tag"></script>
|
<script src="tags/image-date.riot" type="riot/tag"></script>
|
||||||
<script src="tags/pagination.riot" type="riot/tag"></script>
|
<script src="tags/image-content-digest.riot" type="riot/tag"></script>
|
||||||
<script src="tags/app.riot" type="riot/tag"></script>
|
<script src="tags/pagination.riot" type="riot/tag"></script>
|
||||||
<script src="scripts/http.js"></script>
|
<script src="tags/app.riot" type="riot/tag"></script>
|
||||||
<script src="scripts/script.js"></script>
|
<script src="scripts/http.js"></script>
|
||||||
<script src="scripts/utils.js"></script>
|
<script src="scripts/script.js"></script>
|
||||||
<!-- endbuild -->
|
<script src="scripts/utils.js"></script>
|
||||||
</body>
|
<!-- endbuild -->
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -76,7 +76,10 @@ export function getHistoryIcon(attribute) {
|
||||||
case 'ExposedPorts':
|
case 'ExposedPorts':
|
||||||
return 'router';
|
return 'router';
|
||||||
default:
|
default:
|
||||||
'';
|
if (attribute.startsWith('custom-label-')) {
|
||||||
|
return 'label';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,3 +204,7 @@ export function decodeURI(url) {
|
||||||
export function truthy(value) {
|
export function truthy(value) {
|
||||||
return value === true || value === 'true';
|
return value === true || value === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function stringToArray(value) {
|
||||||
|
return value && typeof value === 'string' ? value.split(',') : [];
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue