mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2025-04-29 00:19:54 +03:00
feat(riot-mui): upgrade riot mui and all dependencies (#279)
I [forked riot-mui](https://github.com/Joxit/riot-5-mui) in 2021 to be compatible with [riot.js 5+](https://riot.js.org/) because they change a lot of stuff. This was bundled in 2.0.0 of docker-registry-ui (see https://github.com/Joxit/docker-registry-ui/pull/176) Now im improving riot-mui's DX to be more component oriented and add new features in the library. Major changes: * CTRL + click on buttons (catalog <=> taglist; taglist <=> tag-history) * Fix history multi-arch tabs * Fix tag list pagination (creation date missing) This is still a work in progress but I'm integrating this in Docker-Registry-UI. It will help to have new features like dark mode or custom UI. Stay tuned!
This commit is contained in:
commit
a0dcc84ca6
21 changed files with 277 additions and 251 deletions
35
package.json
35
package.json
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "docker-registry-ui",
|
"name": "docker-registry-ui",
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"format": "npm run format-html && npm run format-js && npm run format-riot",
|
"format": "npm run format-html && npm run format-js && npm run format-riot",
|
||||||
"format-html": "find src rollup rollup.config.js -name '*.html' -exec prettier --config .prettierrc -w --parser html {} \\;",
|
"format-html": "find src rollup rollup.config.js -name '*.html' -exec prettier --config .prettierrc -w --parser html {} \\;",
|
||||||
|
@ -18,28 +19,28 @@
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"description": "A web UI for private docker registry",
|
"description": "A web UI for private docker registry",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.17.9",
|
"@babel/core": "^7.20.5",
|
||||||
"@babel/preset-env": "^7.16.0",
|
"@babel/preset-env": "^7.20.2",
|
||||||
"@riotjs/compiler": "^6.1.3",
|
"@riotjs/compiler": "^6.4.2",
|
||||||
"@riotjs/observable": "^4.1.1",
|
"@riotjs/observable": "^4.1.1",
|
||||||
"@riotjs/route": "^8.0.1",
|
"@riotjs/route": "^8.0.2",
|
||||||
"@rollup/plugin-babel": "^5.2.2",
|
"@rollup/plugin-babel": "^6.0.3",
|
||||||
"@rollup/plugin-commonjs": "^21.1.0",
|
"@rollup/plugin-commonjs": "^23.0.3",
|
||||||
"@rollup/plugin-html": "^0.2.4",
|
"@rollup/plugin-html": "^1.0.1",
|
||||||
"@rollup/plugin-json": "^4.1.0",
|
"@rollup/plugin-json": "^5.0.2",
|
||||||
"@rollup/plugin-node-resolve": "^13.2.1",
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||||
"core-js": "^3.22.0",
|
"core-js": "^3.26.1",
|
||||||
"node-sass": "^7.0.1",
|
"node-sass": "^8.0.0",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^2.8.0",
|
||||||
"riot": "^6.1.2",
|
"riot": "^7.1.0",
|
||||||
"riot-mui": "github:joxit/riot-5-mui#4d68d7f",
|
"riot-mui": "github:joxit/riot-5-mui#a9b0ce4",
|
||||||
"rollup": "^2.70.2",
|
"rollup": "^3.5.1",
|
||||||
"rollup-plugin-app-utils": "^1.0.6",
|
"rollup-plugin-app-utils": "^1.0.6",
|
||||||
"rollup-plugin-commonjs": "^10.1.0",
|
"rollup-plugin-commonjs": "^10.1.0",
|
||||||
"rollup-plugin-copy": "^3.4.0",
|
"rollup-plugin-copy": "^3.4.0",
|
||||||
"rollup-plugin-riot": "^6.0.0",
|
"rollup-plugin-riot": "^6.0.0",
|
||||||
"rollup-plugin-scss": "^3.0.0",
|
"rollup-plugin-scss": "^4.0.0",
|
||||||
"rollup-plugin-serve": "^1.1.0",
|
"rollup-plugin-serve": "^2.0.2",
|
||||||
"rollup-plugin-styles": "^4.0.0",
|
"rollup-plugin-styles": "^4.0.0",
|
||||||
"rollup-plugin-terser": "^7.0.2"
|
"rollup-plugin-terser": "^7.0.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,12 @@ import { babel } from '@rollup/plugin-babel';
|
||||||
import scss from 'rollup-plugin-scss';
|
import scss from 'rollup-plugin-scss';
|
||||||
import serve from 'rollup-plugin-serve';
|
import serve from 'rollup-plugin-serve';
|
||||||
import html from '@rollup/plugin-html';
|
import html from '@rollup/plugin-html';
|
||||||
import htmlUseref from './rollup/html-useref';
|
import htmlUseref from './rollup/html-useref.js';
|
||||||
import json from '@rollup/plugin-json';
|
import json from '@rollup/plugin-json';
|
||||||
import copy from 'rollup-plugin-copy';
|
import copy from 'rollup-plugin-copy';
|
||||||
import copyTransform from './rollup/copy-transform';
|
import copyTransform from './rollup/copy-transform.js';
|
||||||
import license from './rollup/license';
|
import license from './rollup/license.js';
|
||||||
import checkOutput from './rollup/check-output';
|
import checkOutput from './rollup/check-output.js';
|
||||||
|
|
||||||
const useServe = process.env.ROLLUP_SERVE === 'true';
|
const useServe = process.env.ROLLUP_SERVE === 'true';
|
||||||
const output = useServe ? '.serve' : 'dist';
|
const output = useServe ? '.serve' : 'dist';
|
||||||
|
@ -22,7 +22,7 @@ const plugins = [
|
||||||
json(),
|
json(),
|
||||||
nodeResolve(),
|
nodeResolve(),
|
||||||
commonjs(),
|
commonjs(),
|
||||||
scss({ output: `./${output}/docker-registry-ui.css`, outputStyle: 'compressed' }),
|
scss({ fileName: `docker-registry-ui.css`, outputStyle: 'compressed' }),
|
||||||
babel({ babelHelpers: 'bundled', presets: [['@babel/env', { useBuiltIns: 'usage', corejs: { version: '2' } }]] }),
|
babel({ babelHelpers: 'bundled', presets: [['@babel/env', { useBuiltIns: 'usage', corejs: { version: '2' } }]] }),
|
||||||
copy({
|
copy({
|
||||||
targets: [
|
targets: [
|
||||||
|
|
|
@ -21,7 +21,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
if="{!props.filterResults || state.nImages > 0 || matchSearch(props.filterResults, state.image)}"
|
if="{!props.filterResults || state.nImages > 0 || matchSearch(props.filterResults, state.image)}"
|
||||||
>
|
>
|
||||||
<material-card class="list highlight" expanded="{state.expanded}" onclick="{ onClick }">
|
<material-card class="list highlight" expanded="{state.expanded}" onclick="{ onClick }">
|
||||||
|
<a if="{ state.image }" href="{ router.taglist(state.image) }">
|
||||||
<material-waves center="true" color="#ddd"></material-waves>
|
<material-waves center="true" color="#ddd"></material-waves>
|
||||||
|
</a>
|
||||||
|
<material-waves if="{ state.images }" center="true" color="#ddd"></material-waves>
|
||||||
<span>
|
<span>
|
||||||
<i class="material-icons">send</i>
|
<i class="material-icons">send</i>
|
||||||
{ state.image || state.repo }
|
{ state.image || state.repo }
|
||||||
|
@ -76,9 +79,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
},
|
},
|
||||||
onClick() {
|
onClick() {
|
||||||
const state = this.state;
|
const state = this.state;
|
||||||
if (!state.repo) {
|
if (state.repo) {
|
||||||
router.taglist(state.image);
|
|
||||||
} else {
|
|
||||||
this.update({
|
this.update({
|
||||||
expanded: !this.state.expanded,
|
expanded: !this.state.expanded,
|
||||||
expanding: true,
|
expanding: true,
|
||||||
|
@ -112,6 +113,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
oReq.send();
|
oReq.send();
|
||||||
},
|
},
|
||||||
matchSearch,
|
matchSearch,
|
||||||
|
router,
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<!-- End of tag -->
|
<!-- End of tag -->
|
||||||
|
|
|
@ -16,16 +16,16 @@
|
||||||
-->
|
-->
|
||||||
<add-registry-url>
|
<add-registry-url>
|
||||||
<material-popup opened="{ props.opened }" onClick="{ props.onClose }">
|
<material-popup opened="{ props.opened }" onClick="{ props.onClose }">
|
||||||
<div slot="title">Add your Server ?</div>
|
<div class="material-popup-title">Add your Server ?</div>
|
||||||
<div slot="content">
|
<div class="material-popup-content">
|
||||||
<material-input onkeyup="{ onKeyUp }" placeholder="Server URL"></material-input>
|
<material-input onkeyup="{ onKeyUp }" label="Server URL" label-color="#666" valid="{ registryUrlValidator }"></material-input>
|
||||||
<span>Write your URL without /v2</span>
|
<span>Write your URL without /v2</span>
|
||||||
</div>
|
</div>
|
||||||
<div slot="action">
|
<div class="material-popup-action">
|
||||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ add }">
|
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ add }" color="#000" inverted>
|
||||||
Add
|
Add
|
||||||
</material-button>
|
</material-button>
|
||||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ props.onClose }">
|
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ props.onClose }" color="#000" inverted>
|
||||||
Cancel
|
Cancel
|
||||||
</material-button>
|
</material-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,6 +55,9 @@
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
setTimeout(() => router.updateUrlQueryParam(url), 100);
|
setTimeout(() => router.updateUrlQueryParam(url), 100);
|
||||||
},
|
},
|
||||||
|
registryUrlValidator(input) {
|
||||||
|
return /^https?:\/\//.test(input) && !/\/v2\/?$/.test(input)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
</add-registry-url>
|
</add-registry-url>
|
||||||
|
|
|
@ -15,18 +15,18 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<change-registry-url>
|
<change-registry-url>
|
||||||
<material-popup opened="{ props.opened }" onClick="{ props.onClick }">
|
<material-popup opened="{ props.opened }" onClick="{ props.onClose }">
|
||||||
<div slot="title">Change your Server ?</div>
|
<div class="material-popup-title">Change your Server ?</div>
|
||||||
<div slot="content">
|
<div class="material-popup-content">
|
||||||
<select>
|
<select>
|
||||||
<option each="{ url in getRegistryServers() }" value="{ url }">{ url }</option>
|
<option each="{ url in getRegistryServers() }" value="{ url }">{ url }</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div slot="action">
|
<div class="material-popup-action">
|
||||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ change }">
|
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ change }" color="#000" inverted>
|
||||||
Change
|
Change
|
||||||
</material-button>
|
</material-button>
|
||||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ props.onClose }">
|
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ props.onClose }" color="#000" inverted>
|
||||||
Cancel
|
Cancel
|
||||||
</material-button>
|
</material-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -62,6 +62,7 @@
|
||||||
background: 0 0;
|
background: 0 0;
|
||||||
border: none;
|
border: none;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
font-size: 1em;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border-bottom: 1px solid #2f6975;
|
border-bottom: 1px solid #2f6975;
|
||||||
|
|
|
@ -16,17 +16,17 @@
|
||||||
-->
|
-->
|
||||||
<confirm-delete-image>
|
<confirm-delete-image>
|
||||||
<material-popup opened="{ props.opened }" onClick="{ props.onClick }">
|
<material-popup opened="{ props.opened }" onClick="{ props.onClick }">
|
||||||
<div slot="title">These images will be deleted</div>
|
<div class="material-popup-title">These images will be deleted</div>
|
||||||
<div slot="content">
|
<div class="material-popup-content">
|
||||||
<ul>
|
<ul>
|
||||||
<li each="{ image in displayImagesToDelete(props.toDelete, props.tags) }">{ image.name }:{ image.tag }</li>
|
<li each="{ image in displayImagesToDelete(props.toDelete, props.tags) }">{ image.name }:{ image.tag }</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div slot="action">
|
<div class="material-popup-action">
|
||||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ deleteImages }">
|
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ deleteImages }" color="#000" inverted>
|
||||||
Delete
|
Delete
|
||||||
</material-button>
|
</material-button>
|
||||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ props.onClick }">
|
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ props.onClick }" color="#000" inverted>
|
||||||
Cancel
|
Cancel
|
||||||
</material-button>
|
</material-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -35,15 +35,23 @@
|
||||||
on-notify="{ props.onNotify }"
|
on-notify="{ props.onNotify }"
|
||||||
on-server-change="{ props.onServerChange }"
|
on-server-change="{ props.onServerChange }"
|
||||||
></remove-registry-url>
|
></remove-registry-url>
|
||||||
<div class="container">
|
<div class="material-dropdown-wrapper">
|
||||||
<material-button onClick="{ onClick }" waves-center="true" rounded="true" waves-opacity="0.6" waves-duration="600">
|
<material-button
|
||||||
|
onClick="{ onClick }"
|
||||||
|
waves-center="true"
|
||||||
|
waves-opacity="0.6"
|
||||||
|
waves-duration="600"
|
||||||
|
color="rgba(0,0,0,0)"
|
||||||
|
text-color="#fff"
|
||||||
|
icon
|
||||||
|
>
|
||||||
<i class="material-icons">more_vert</i>
|
<i class="material-icons">more_vert</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
<material-dropdown-list
|
<material-dropdown
|
||||||
items="{ dropdownItems.filter(item => item.ro || !props.readOnlyRegistries) }"
|
items="{ dropdownItems.filter(item => item.ro || !props.readOnlyRegistries) }"
|
||||||
onSelect="{ onDropdownSelect }"
|
on-click="{ onDropdownSelect }"
|
||||||
opened="{ state.isDropdownOpened }"
|
opened="{ state.isDropdownOpened }"
|
||||||
/>
|
></material-dropdown>
|
||||||
</div>
|
</div>
|
||||||
<div class="overlay" onclick="{ onClick }" if="{ state.isDropdownOpened }"></div>
|
<div class="overlay" onclick="{ onClick }" if="{ state.isDropdownOpened }"></div>
|
||||||
<script>
|
<script>
|
||||||
|
@ -74,9 +82,9 @@
|
||||||
ro: false,
|
ro: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
onDropdownSelect(key, item) {
|
onDropdownSelect(event) {
|
||||||
this.update({
|
this.update({
|
||||||
[item.name]: true,
|
[event.target.item]: true,
|
||||||
isDropdownOpened: false,
|
isDropdownOpened: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -96,15 +104,17 @@
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
:host > .container {
|
:host > .material-dropdown-wrapper {
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
right: 16px;
|
|
||||||
color: #000;
|
color: #000;
|
||||||
list-style-type: disc;
|
list-style-type: disc;
|
||||||
margin-block-start: 0.7em;
|
margin-block-start: 0.7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:host .material-dropdown-wrapper material-dropdown .material-dropdown-container {
|
||||||
|
right: 0;
|
||||||
|
top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
:host .overlay {
|
:host .overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -114,33 +124,15 @@
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host material-button {
|
:host material-button button {
|
||||||
background: rgba(255, 255, 255, 0);
|
|
||||||
float: right;
|
float: right;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host material-button .content i.material-icons {
|
:host material-button .content i.material-icons {
|
||||||
color: #fff;
|
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host material-dropdown-list {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host material-dropdown-list ul.dropdown-content {
|
|
||||||
min-width: 156px;
|
|
||||||
padding: 8px 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host material-dropdown-list ul.dropdown-content li span {
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host material-popup * {
|
:host material-popup * {
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,17 +16,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<remove-registry-url>
|
<remove-registry-url>
|
||||||
<material-popup opened="{ props.opened }" onClick="{ props.onClose }">
|
<material-popup opened="{ props.opened }" onClick="{ props.onClose }">
|
||||||
<div slot="title">Remove your Registry Server ?</div>
|
<div class="material-popup-title">Remove your Registry Server ?</div>
|
||||||
<div slot="content">
|
<div class="material-popup-content">
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li each="{ url in getRegistryServers() }">
|
<li each="{ url in getRegistryServers() }">
|
||||||
<span>
|
<span>
|
||||||
<material-button
|
<material-button
|
||||||
onClick="{ remove }"
|
onClick="{ remove(url) }"
|
||||||
url="{ url }"
|
url="{ url }"
|
||||||
rounded="true"
|
|
||||||
waves-color="rgba(158,158,158,.4)"
|
waves-color="rgba(158,158,158,.4)"
|
||||||
waves-center="true"
|
waves-center="true"
|
||||||
|
inverted
|
||||||
|
icon
|
||||||
>
|
>
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
|
@ -35,8 +36,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div slot="action">
|
<div class="material-popup-action">
|
||||||
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ props.onClose }">
|
<material-button class="dialog-button" waves-color="rgba(158,158,158,.4)" onClick="{ props.onClose }" color="#000" inverted>
|
||||||
Close
|
Close
|
||||||
</material-button>
|
</material-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -44,10 +45,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<script>
|
<script>
|
||||||
import { getRegistryServers, removeRegistryServers } from '../../scripts/utils';
|
import { getRegistryServers, removeRegistryServers } from '../../scripts/utils';
|
||||||
export default {
|
export default {
|
||||||
remove(event) {
|
remove(url) {
|
||||||
const url = event.currentTarget.attributes.url && event.currentTarget.attributes.url.value;
|
return (event) => {
|
||||||
|
console.log(url, event)
|
||||||
removeRegistryServers(url);
|
removeRegistryServers(url);
|
||||||
setTimeout(() => this.update(), 100);
|
setTimeout(() => this.update(), 100);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getRegistryServers,
|
getRegistryServers,
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<docker-registry-ui>
|
<docker-registry-ui>
|
||||||
<header>
|
<header>
|
||||||
<material-navbar>
|
<material-navbar>
|
||||||
<div class="logo">Docker Registry UI</div>
|
<span class="logo">Docker Registry UI</span>
|
||||||
|
<div class="menu">
|
||||||
<search-bar on-search="{ onSearch }"></search-bar>
|
<search-bar on-search="{ onSearch }"></search-bar>
|
||||||
<dialogs-menu
|
<dialogs-menu
|
||||||
if="{props.singleRegistry !== 'true'}"
|
if="{props.singleRegistry !== 'true'}"
|
||||||
|
@ -26,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
default-registries="{ props.defaultRegistries }"
|
default-registries="{ props.defaultRegistries }"
|
||||||
read-only-registries="{ truthy(props.readOnlyRegistries) }"
|
read-only-registries="{ truthy(props.readOnlyRegistries) }"
|
||||||
></dialogs-menu>
|
></dialogs-menu>
|
||||||
|
</div>
|
||||||
</material-navbar>
|
</material-navbar>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
|
@ -81,9 +83,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<material-snackbar message="{ state.snackbarMessage }" is-error="{ state.snackbarIsError }"></material-snackbar>
|
<material-snackbar message="{ state.snackbarMessage }" is-error="{ state.snackbarIsError }"></material-snackbar>
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
<material-footer>
|
<material-footer mini="true">
|
||||||
<a slot="logo" href="https://joxit.github.io/docker-registry-ui/">Docker Registry UI { version }</a>
|
<a class="material-footer-logo" href="https://joxit.github.io/docker-registry-ui/">Docker Registry UI { version }</a>
|
||||||
<ul slot="link-list">
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a href="https://github.com/Joxit/docker-registry-ui">Contribute on GitHub</a>
|
<a href="https://github.com/Joxit/docker-registry-ui">Contribute on GitHub</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -197,4 +199,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
stringToArray,
|
stringToArray,
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
material-navbar {
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
material-navbar .menu {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</docker-registry-ui>
|
</docker-registry-ui>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<search-bar>
|
<search-bar>
|
||||||
<material-input placeholder="Search in page"></material-input>
|
<material-input label="Search in page" text-color="#fff" label-color="#aaa"></material-input>
|
||||||
<script>
|
<script>
|
||||||
import { router } from '@riotjs/route';
|
import { router } from '@riotjs/route';
|
||||||
|
|
||||||
|
@ -39,10 +39,9 @@
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
:host material-input {
|
:host material-input {
|
||||||
position: absolute;
|
line-height: initial;
|
||||||
top: 0em;
|
|
||||||
right: 64px;
|
|
||||||
max-width: 20%;
|
max-width: 20%;
|
||||||
|
min-width: 13em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 400px) {
|
@media screen and (max-width: 400px) {
|
||||||
|
|
|
@ -15,9 +15,17 @@ 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>
|
<tag-history>
|
||||||
<material-card ref="tag-history-tag" class="tag-history header">
|
<material-card>
|
||||||
<div class="material-card-title-action">
|
<div class="material-card-title-action">
|
||||||
<material-button waves-center="true" rounded="true" waves-color="#ddd" onClick="{ toTaglist }">
|
<material-button
|
||||||
|
color="#777"
|
||||||
|
waves-center="true"
|
||||||
|
rounded="true"
|
||||||
|
waves-color="#ddd"
|
||||||
|
href="{ toTaglist() }"
|
||||||
|
inverted
|
||||||
|
icon
|
||||||
|
>
|
||||||
<i class="material-icons">arrow_back</i>
|
<i class="material-icons">arrow_back</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
<h2>History of { props.image }:{ props.tag } <i class="material-icons">history</i></h2>
|
<h2>History of { props.image }:{ props.tag } <i class="material-icons">history</i></h2>
|
||||||
|
@ -29,12 +37,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
<material-tabs
|
<material-tabs
|
||||||
if="{ state.archs && state.loadend }"
|
if="{ state.archs && state.loadend }"
|
||||||
|
color="#25313b"
|
||||||
|
text-color="#fff"
|
||||||
useLine="{ true }"
|
useLine="{ true }"
|
||||||
tabs="{ state.archs }"
|
tabs="{ state.archs }"
|
||||||
onTabChanged="{ onTabChanged }"
|
onTabChanged="{ onTabChanged }"
|
||||||
|
inverted
|
||||||
></material-tabs>
|
></material-tabs>
|
||||||
|
|
||||||
<material-card each="{ element in state.elements }" class="tag-history-element">
|
<material-card each="{ element in state.elements }">
|
||||||
<tag-history-element
|
<tag-history-element
|
||||||
each="{ entry in element }"
|
each="{ entry in element }"
|
||||||
if="{ entry.value && entry.value.length > 0}"
|
if="{ entry.value && entry.value.length > 0}"
|
||||||
|
@ -128,7 +139,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
toTaglist() {
|
toTaglist() {
|
||||||
router.taglist(this.props.image);
|
return router.taglist(this.props.image);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const eltIdx = function (e) {
|
const eltIdx = function (e) {
|
||||||
|
|
|
@ -18,11 +18,13 @@
|
||||||
<div class="copy-to-clipboard">
|
<div class="copy-to-clipboard">
|
||||||
<input style="display: none; width: 1px; height: 1px" value="{ getDockerCmd(props) }" />
|
<input style="display: none; width: 1px; height: 1px" value="{ getDockerCmd(props) }" />
|
||||||
<material-button
|
<material-button
|
||||||
waves-center="true"
|
color="rgba(0,0,0,0)"
|
||||||
rounded="true"
|
text-color="#777"
|
||||||
waves-color="#ddd"
|
waves-color="#ddd"
|
||||||
|
waves-center="true"
|
||||||
onClick="{ copy }"
|
onClick="{ copy }"
|
||||||
title="Copy pull command."
|
title="Copy pull command."
|
||||||
|
icon
|
||||||
>
|
>
|
||||||
<i class="material-icons">content_copy</i>
|
<i class="material-icons">content_copy</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
|
|
|
@ -20,6 +20,13 @@
|
||||||
import { dateFormat } from '../../scripts/utils';
|
import { dateFormat } from '../../scripts/utils';
|
||||||
export default {
|
export default {
|
||||||
onMounted(props) {
|
onMounted(props) {
|
||||||
|
this.loadCreationDate(props);
|
||||||
|
},
|
||||||
|
onUpdated(props) {
|
||||||
|
this.loadCreationDate(props);
|
||||||
|
},
|
||||||
|
loadCreationDate(props) {
|
||||||
|
if (!props.image.creationDate && !props.image.ociImage) {
|
||||||
props.image.one('creation-date', (date) => {
|
props.image.one('creation-date', (date) => {
|
||||||
this.update({
|
this.update({
|
||||||
date: date,
|
date: date,
|
||||||
|
@ -27,6 +34,7 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
props.image.trigger('get-date');
|
props.image.trigger('get-date');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getDate(image) {
|
getDate(image) {
|
||||||
return !image.ociImage ? `${dateFormat(image.creationDate)} ago` : 'Not Available';
|
return !image.ociImage ? `${dateFormat(image.creationDate)} ago` : 'Not Available';
|
||||||
|
|
|
@ -15,19 +15,56 @@ 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/>.
|
||||||
-->
|
-->
|
||||||
<pagination>
|
<pagination>
|
||||||
<div class="conatianer">
|
<div class="container">
|
||||||
<div class="pagination-centered">
|
<div class="pagination-centered">
|
||||||
<material-button
|
<material-button
|
||||||
aria-label="page-{ p.page }"
|
aria-label="page-{ p.page }"
|
||||||
|
color="rgba(0, 0, 0, { p.current ? 0.12 : 0 } )"
|
||||||
|
text-color="#000"
|
||||||
waves-color="rgba(158,158,158,.4)"
|
waves-color="rgba(158,158,158,.4)"
|
||||||
each="{ (p, idx) in props.pages}"
|
each="{ (p, idx) in props.pages}"
|
||||||
class="{ p.current ? 'current' : ''} { p['space-left'] ? 'space-left' : '' } { p['space-right'] ? 'space-right' : ''}"
|
class="{ p.current ? 'current' : ''} { p['space-left'] ? 'space-left' : '' } { p['space-right'] ? 'space-right' : ''}"
|
||||||
onClick="{() => props.onPageUpdate(idx)}"
|
onClick="{(e) => props.onPageUpdate(idx)}"
|
||||||
|
outlined
|
||||||
>
|
>
|
||||||
<i if="{ p.icon }" class="material-icons">{ p.icon }</i>
|
<i if="{ p.icon }" class="material-icons">{ p.icon }</i>
|
||||||
<div if="{ !p.icon }">{ p.page }</div>
|
<template if="{ !p.icon }">{ p.page }</template>
|
||||||
</material-button>
|
</material-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script></script>
|
<script></script>
|
||||||
|
<style>
|
||||||
|
:host .container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host .container .pagination-centered {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host material-button > :first-child {
|
||||||
|
padding: 0;
|
||||||
|
min-width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host material-button > :first-child .content {
|
||||||
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host material-button.current > :first-child.space-left {
|
||||||
|
margin-left: 85px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host material-button.current > :first-child.space-right {
|
||||||
|
margin-right: 85px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host material-button .content i.material-icons {
|
||||||
|
height: unset;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</pagination>
|
</pagination>
|
||||||
|
|
|
@ -16,13 +16,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<remove-image>
|
<remove-image>
|
||||||
<material-button
|
<material-button
|
||||||
waves-center="true"
|
color="rgba(0,0,0,0)"
|
||||||
rounded="true"
|
text-color="#777"
|
||||||
waves-color="#ddd"
|
waves-color="#ddd"
|
||||||
|
waves-center="true"
|
||||||
title="This will delete the image."
|
title="This will delete the image."
|
||||||
if="{ !props.multiDelete }"
|
if="{ !props.multiDelete }"
|
||||||
disabled="{ !state.contentDigest }"
|
disabled="{ !state.contentDigest }"
|
||||||
onClick="{ deleteImage }"
|
onClick="{ deleteImage }"
|
||||||
|
icon
|
||||||
>
|
>
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
|
@ -56,8 +58,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
deleteImage() {
|
deleteImage() {
|
||||||
this.props.handleCheckboxChange(ACTION_DELETE_IMAGE, this.props.image);
|
this.props.handleCheckboxChange(ACTION_DELETE_IMAGE, this.props.image);
|
||||||
},
|
},
|
||||||
handleCheckboxChange(checked) {
|
handleCheckboxChange(event) {
|
||||||
const action = checked ? ACTION_CHECK_TO_DELETE : ACTION_UNCHECK_TO_DELETE;
|
const action = event.target.checked ? ACTION_CHECK_TO_DELETE : ACTION_UNCHECK_TO_DELETE;
|
||||||
this.props.handleCheckboxChange(action, this.props.image);
|
this.props.handleCheckboxChange(action, this.props.image);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,11 +17,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<tag-history-button>
|
<tag-history-button>
|
||||||
<material-button
|
<material-button
|
||||||
title="{ buttonTittle() }"
|
title="{ buttonTittle() }"
|
||||||
waves-center="true"
|
color="rgba(0,0,0,0)"
|
||||||
rounded="true"
|
text-color="#777"
|
||||||
waves-color="#ddd"
|
waves-color="#ddd"
|
||||||
onClick="{ routeToHistory }"
|
waves-center="true"
|
||||||
|
href="{ routeToHistory() }"
|
||||||
disabled="{ props.image.ociImage }"
|
disabled="{ props.image.ociImage }"
|
||||||
|
icon
|
||||||
>
|
>
|
||||||
<i class="material-icons">history</i>
|
<i class="material-icons">history</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
|
@ -40,7 +42,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
},
|
},
|
||||||
routeToHistory() {
|
routeToHistory() {
|
||||||
if (!this.props.image.ociImage) {
|
if (!this.props.image.ociImage) {
|
||||||
router.history(this.props.image.name, this.props.image.tag);
|
return router.history(this.props.image.name, this.props.image.tag);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<tag-list>
|
<tag-list>
|
||||||
<material-card class="header">
|
<material-card class="header">
|
||||||
<div class="material-card-title-action">
|
<div class="material-card-title-action">
|
||||||
<material-button waves-center="true" rounded="true" waves-color="#ddd" onClick="{ router.home }">
|
<material-button
|
||||||
|
color="#777"
|
||||||
|
waves-color="#ddd"
|
||||||
|
waves-center="true"
|
||||||
|
href="{ router.home() }"
|
||||||
|
icon
|
||||||
|
inverted
|
||||||
|
>
|
||||||
<i class="material-icons">arrow_back</i>
|
<i class="material-icons">arrow_back</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
<h2>
|
<h2>
|
||||||
|
|
|
@ -63,12 +63,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
>
|
>
|
||||||
</material-checkbox>
|
</material-checkbox>
|
||||||
<material-button
|
<material-button
|
||||||
|
if="{ state.toDelete.size > 0 && !state.singleDeleteAction }"
|
||||||
waves-center="true"
|
waves-center="true"
|
||||||
rounded="true"
|
color="#fff"
|
||||||
|
text-color="#777"
|
||||||
waves-color="#ddd"
|
waves-color="#ddd"
|
||||||
title="This will delete selected images."
|
title="This will delete selected images."
|
||||||
onClick="{ deleteImages }"
|
onClick="{ deleteImages }"
|
||||||
if="{ state.toDelete.size > 0 && !state.singleDeleteAction }"
|
icon
|
||||||
>
|
>
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
|
@ -78,31 +80,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr each="{ image in getPage(props.tags, props.page) }" if="{ matchSearch(props.filterResults, image.tag) }">
|
<tr each="{ image in getPage(props.tags, props.page) }" if="{ matchSearch(props.filterResults, image.tag) }">
|
||||||
<td class="creation-date">
|
<td class="creation-date">
|
||||||
<image-date image="{ image }" />
|
<image-date image="{ image }"></image-date>
|
||||||
</td>
|
</td>
|
||||||
<td class="image-size">
|
<td class="image-size">
|
||||||
<image-size image="{ image }" />
|
<image-size image="{ image }"></image-size>
|
||||||
</td>
|
</td>
|
||||||
<td if="{ props.showContentDigest }">
|
<td if="{ props.showContentDigest }">
|
||||||
<image-content-digest image="{ image }" />
|
<image-content-digest image="{ image }"></image-content-digest>
|
||||||
<copy-to-clipboard
|
<copy-to-clipboard
|
||||||
target="digest"
|
target="digest"
|
||||||
image="{ image }"
|
image="{ image }"
|
||||||
pull-url="{ props.pullUrl }"
|
pull-url="{ props.pullUrl }"
|
||||||
on-notify="{ props.onNotify }"
|
on-notify="{ props.onNotify }"
|
||||||
/>
|
></copy-to-clipboard>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<image-tag image="{ image }" />
|
<image-tag image="{ image }"></image-tag>
|
||||||
<copy-to-clipboard
|
<copy-to-clipboard
|
||||||
target="tag"
|
target="tag"
|
||||||
image="{ image }"
|
image="{ image }"
|
||||||
pull-url="{ props.pullUrl }"
|
pull-url="{ props.pullUrl }"
|
||||||
on-notify="{ props.onNotify }"
|
on-notify="{ props.onNotify }"
|
||||||
/>
|
></copy-to-clipboard>
|
||||||
</td>
|
</td>
|
||||||
<td class="show-tag-history">
|
<td class="show-tag-history">
|
||||||
<tag-history-button image="{ image }" />
|
<tag-history-button image="{ image }"></tag-history-button>
|
||||||
</td>
|
</td>
|
||||||
<td if="{ props.isImageRemoveActivated }" class="remove-tag">
|
<td if="{ props.isImageRemoveActivated }" class="remove-tag">
|
||||||
<remove-image
|
<remove-image
|
||||||
|
@ -113,7 +115,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
checked="{ state.toDelete.has(image) }"
|
checked="{ state.toDelete.has(image) }"
|
||||||
on-notify="{ props.onNotify }"
|
on-notify="{ props.onNotify }"
|
||||||
on-authentication="{ props.onAuthentication }"
|
on-authentication="{ props.onAuthentication }"
|
||||||
/>
|
></remove-image>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -172,7 +174,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
confirmDeleteImage: false,
|
confirmDeleteImage: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onRemoveImageHeaderChange(checked, event) {
|
onRemoveImageHeaderChange(event) {
|
||||||
if (event.altKey === true) {
|
if (event.altKey === true) {
|
||||||
const tags = getPage(this.props.tags, this.props.page);
|
const tags = getPage(this.props.tags, this.props.page);
|
||||||
tags
|
tags
|
||||||
|
@ -184,7 +186,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.update({
|
this.update({
|
||||||
multiDelete: checked,
|
multiDelete: event.target.checked,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
MaterialCheckbox,
|
MaterialCheckbox,
|
||||||
MaterialTabs,
|
MaterialTabs,
|
||||||
MaterialSnackbar,
|
MaterialSnackbar,
|
||||||
MaterialDropdownList,
|
MaterialDropdown,
|
||||||
MaterialPopup,
|
MaterialPopup,
|
||||||
MaterialInput,
|
MaterialInput,
|
||||||
} from 'riot-mui';
|
} from 'riot-mui';
|
||||||
|
@ -28,7 +28,7 @@ register('material-waves', MaterialWaves);
|
||||||
register('material-checkbox', MaterialCheckbox);
|
register('material-checkbox', MaterialCheckbox);
|
||||||
register('material-snackbar', MaterialSnackbar);
|
register('material-snackbar', MaterialSnackbar);
|
||||||
register('material-tabs', MaterialTabs);
|
register('material-tabs', MaterialTabs);
|
||||||
register('material-dropdown-list', MaterialDropdownList);
|
register('material-dropdown', MaterialDropdown);
|
||||||
register('material-popup', MaterialPopup);
|
register('material-popup', MaterialPopup);
|
||||||
register('material-input', MaterialInput);
|
register('material-input', MaterialInput);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
||||||
*/
|
*/
|
||||||
import { router, getCurrentRoute } from '@riotjs/route';
|
import { getCurrentRoute } from '@riotjs/route';
|
||||||
import { encodeURI, decodeURI } from './utils';
|
import { encodeURI, decodeURI } from './utils';
|
||||||
|
|
||||||
function getQueryParams() {
|
function getQueryParams() {
|
||||||
|
@ -59,16 +59,16 @@ function baseUrl(qs) {
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
home() {
|
home() {
|
||||||
router.push(baseUrl({ page: null }));
|
return baseUrl({ page: null });
|
||||||
},
|
},
|
||||||
taglist(image) {
|
taglist(image) {
|
||||||
router.push(`${baseUrl({ page: null })}#!/taglist/${image}`);
|
return `${baseUrl({ page: null })}#!/taglist/${image}`;
|
||||||
},
|
},
|
||||||
getTagListImage() {
|
getTagListImage() {
|
||||||
return getCurrentRoute().replace(/^.*(#!)?\/?taglist\//, '');
|
return getCurrentRoute().replace(/^.*(#!)?\/?taglist\//, '');
|
||||||
},
|
},
|
||||||
history(image, tag) {
|
history(image, tag) {
|
||||||
router.push(`${baseUrl({ page: null })}#!/taghistory/image/${image}/tag/${tag}`);
|
return `${baseUrl({ page: null })}#!/taghistory/image/${image}/tag/${tag}`;
|
||||||
},
|
},
|
||||||
getTagHistoryImage() {
|
getTagHistoryImage() {
|
||||||
return getCurrentRoute().replace(/^.*(#!)?\/?taghistory\/image\/(.*)\/tag\/(.*)\/?$/, '$2');
|
return getCurrentRoute().replace(/^.*(#!)?\/?taghistory\/image\/(.*)\/tag\/(.*)\/?$/, '$2');
|
||||||
|
|
157
src/style.scss
157
src/style.scss
|
@ -23,7 +23,7 @@
|
||||||
@import 'riot-mui/src/material-elements/material-checkbox/material-checkbox.scss';
|
@import 'riot-mui/src/material-elements/material-checkbox/material-checkbox.scss';
|
||||||
@import 'riot-mui/src/material-elements/material-tabs/material-tabs.scss';
|
@import 'riot-mui/src/material-elements/material-tabs/material-tabs.scss';
|
||||||
@import 'riot-mui/src/material-elements/material-snackbar/material-snackbar.scss';
|
@import 'riot-mui/src/material-elements/material-snackbar/material-snackbar.scss';
|
||||||
@import 'riot-mui/src/material-elements/material-dropdown-list/material-dropdown-list.scss';
|
@import 'riot-mui/src/material-elements/material-dropdown/material-dropdown.scss';
|
||||||
@import 'riot-mui/src/material-elements/material-popup/material-popup.scss';
|
@import 'riot-mui/src/material-elements/material-popup/material-popup.scss';
|
||||||
@import 'riot-mui/src/material-elements/material-input/material-input.scss';
|
@import 'riot-mui/src/material-elements/material-input/material-input.scss';
|
||||||
|
|
||||||
|
@ -32,9 +32,11 @@
|
||||||
|
|
||||||
html > body {
|
html > body {
|
||||||
font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif !important;
|
font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif !important;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html,
|
||||||
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
@ -59,44 +61,35 @@ html, body {
|
||||||
font-weight: inherit;
|
font-weight: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
material-card, material-tabs, pagination .conatianer {
|
material-card,
|
||||||
|
material-tabs,
|
||||||
|
pagination .container {
|
||||||
max-width: 95%;
|
max-width: 95%;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
pagination .conatianer {
|
|
||||||
display: flex;
|
|
||||||
display: -moz-flex;
|
|
||||||
display: -webkit-flex;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
pagination .conatianer .pagination-centered {
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 1515px * 0.95 = 1440px */
|
/* 1515px * 0.95 = 1440px */
|
||||||
@media screen and (min-width: 1515px) {
|
@media screen and (min-width: 1515px) {
|
||||||
material-card, material-tabs, pagination .conatianer {
|
material-card,
|
||||||
|
material-tabs,
|
||||||
|
pagination .container {
|
||||||
max-width: 1440px;
|
max-width: 1440px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
material-tabs {
|
material-tabs {
|
||||||
display: block;
|
display: block;
|
||||||
-webkit-box-shadow: 0 2px 5px 0 rgba(0,0,0,.16), 0 2px 10px 0 rgba(0,0,0,.12);
|
-webkit-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
|
||||||
-ms-box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);
|
-ms-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
|
||||||
-moz-box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);
|
-moz-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
|
||||||
-o-box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);
|
-o-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
|
||||||
box-shadow: 0 2px 5px 0 rgba(0,0,0,.16), 0 2px 10px 0 rgba(0,0,0,.12);
|
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
material-tabs material-button,
|
material-tabs material-button,
|
||||||
material-tabs material-button .content .text {
|
material-tabs material-button .content .text {
|
||||||
background-color: #fff;
|
|
||||||
color: #aaa;
|
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,20 +110,12 @@ material-spinner {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
material-navbar {
|
|
||||||
height: 64px;
|
|
||||||
}
|
|
||||||
|
|
||||||
material-navbar nav-wrapper {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
padding: 0 16px 0 72px;
|
padding: 0 16px 0 72px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
letter-spacing: .02em;
|
letter-spacing: 0.02em;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,18 +154,22 @@ h2 {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
docker-registry-ui material-button > :first-child .content i.material-icons,
|
||||||
|
docker-registry-ui material-button > :first-child .content i.material-icons.material-icons {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.list > span i.material-icons,
|
.list > span i.material-icons,
|
||||||
.list > li i.material-icons {
|
.list > li i.material-icons {
|
||||||
margin-right: 32px;
|
margin-right: 32px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
font-size: 24px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: #757575;
|
color: #757575;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list > span .right i.material-icons.animated {
|
.list > span .right i.material-icons.animated {
|
||||||
transition: all 350ms cubic-bezier(.4,0,.2,1);
|
transition: all 350ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +226,7 @@ material-card table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid rgba(0, 0, 0, .12);
|
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
@ -250,7 +239,7 @@ material-card table th {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
color: rgba(0, 0, 0, .54);
|
color: rgba(0, 0, 0, 0.54);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0 18px 12px 18px;
|
padding: 0 18px 12px 18px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
@ -260,17 +249,16 @@ material-card table th {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
material-card material-button:hover,
|
material-button:hover > :first-child[inverted='true'],
|
||||||
material-card table tbody tr:hover,
|
material-card .material-card-title-action material-button:hover button,
|
||||||
pagination material-button:hover {
|
material-card table tbody tr:hover {
|
||||||
background-color: #eee;
|
background-color: #eee !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
material-card material-button,
|
material-button > :first-child[inverted='true'],
|
||||||
material-card table tbody tr,
|
material-card table tbody tr {
|
||||||
pagination material-button {
|
transition-duration: 0.28s;
|
||||||
transition-duration: .28s;
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
transition-timing-function: cubic-bezier(.4, 0, .2, 1);
|
|
||||||
transition-property: background-color;
|
transition-property: background-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,8 +271,8 @@ material-card table td {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
border-top: 1px solid rgba(0, 0, 0, .12);
|
border-top: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, .12);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
padding: 12px 18px;
|
padding: 12px 18px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
@ -292,27 +280,30 @@ material-card table td {
|
||||||
}
|
}
|
||||||
|
|
||||||
tag-history-button button:hover,
|
tag-history-button button:hover,
|
||||||
material-card table th.material-card-th-sorted-ascending:hover, material-card table th.material-card-th-sorted-descending:hover {
|
material-card table th.material-card-th-sorted-ascending:hover,
|
||||||
|
material-card table th.material-card-th-sorted-descending:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
material-card table th.material-card-th-sorted-ascending:hover:before, material-card table th.material-card-th-sorted-descending:hover:before {
|
material-card table th.material-card-th-sorted-ascending:hover:before,
|
||||||
color: rgba(0, 0, 0, .26);
|
material-card table th.material-card-th-sorted-descending:hover:before {
|
||||||
|
color: rgba(0, 0, 0, 0.26);
|
||||||
}
|
}
|
||||||
|
|
||||||
material-card table th.material-card-th-sorted-ascending:before, material-card table th.material-card-th-sorted-descending:before {
|
material-card table th.material-card-th-sorted-ascending:before,
|
||||||
|
material-card table th.material-card-th-sorted-descending:before {
|
||||||
font-family: 'Material Icons';
|
font-family: 'Material Icons';
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
content: "\e5d8";
|
content: '\e5d8';
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
vertical-align: sub;
|
vertical-align: sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
material-card table th.material-card-th-sorted-descending:before {
|
material-card table th.material-card-th-sorted-descending:before {
|
||||||
content: "\e5db";
|
content: '\e5db';
|
||||||
}
|
}
|
||||||
|
|
||||||
material-button .content i.material-icons,
|
material-button .content i.material-icons,
|
||||||
|
@ -329,19 +320,13 @@ material-snackbar .toast {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
material-popup material-button,
|
|
||||||
pagination material-button {
|
|
||||||
background-color: #fff;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
material-popup material-button:hover material-waves {
|
material-popup material-button:hover material-waves {
|
||||||
background-color: hsla(0, 0%, 75%, .2);
|
background-color: hsla(0, 0%, 75%, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
material-popup .popup {
|
material-popup .popup > .content {
|
||||||
|
padding: 1em;
|
||||||
max-width: 450px;
|
max-width: 450px;
|
||||||
top: 2em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
|
@ -366,7 +351,8 @@ material-footer {
|
||||||
/* 5 + 2 + 3 + 24 + 3 + 2 + 18 */
|
/* 5 + 2 + 3 + 24 + 3 + 2 + 18 */
|
||||||
padding-right: 57px;
|
padding-right: 57px;
|
||||||
}
|
}
|
||||||
image-tag, .copy-to-clipboard {
|
image-tag,
|
||||||
|
.copy-to-clipboard {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
image-content-digest {
|
image-content-digest {
|
||||||
|
@ -405,28 +391,11 @@ taglist .image-size {
|
||||||
width: 7em;
|
width: 7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
catalog material-card,
|
|
||||||
tag-history material-card {
|
|
||||||
min-height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
tag-history-button button {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
material-card material-button,
|
|
||||||
pagination material-button {
|
|
||||||
max-height: 30px;
|
|
||||||
max-width: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
material-button:hover material-waves {
|
material-button:hover material-waves {
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
material-card material-button,
|
material-card material-button {
|
||||||
pagination material-button {
|
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +405,7 @@ catalog-element material-card {
|
||||||
}
|
}
|
||||||
|
|
||||||
catalog-element catalog-element material-card {
|
catalog-element catalog-element material-card {
|
||||||
transition: all 350ms cubic-bezier(.4,0,.2,1);
|
transition: all 350ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
@ -489,29 +458,3 @@ material-checkbox .checkbox {
|
||||||
material-checkbox .checkbox.checked {
|
material-checkbox .checkbox.checked {
|
||||||
background-color: #777;
|
background-color: #777;
|
||||||
}
|
}
|
||||||
|
|
||||||
pagination material-button {
|
|
||||||
padding: 0.2em 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pagination material-button .content {
|
|
||||||
display: flex;
|
|
||||||
align-content: center;
|
|
||||||
line-height: 1.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pagination material-button.current {
|
|
||||||
border: 1px solid rgba(0, 0, 0, .12);
|
|
||||||
}
|
|
||||||
|
|
||||||
pagination material-button.current.space-left {
|
|
||||||
margin-left: 85px;
|
|
||||||
}
|
|
||||||
|
|
||||||
pagination material-button.current.space-right {
|
|
||||||
margin-right: 85px;
|
|
||||||
}
|
|
||||||
|
|
||||||
pagination material-button .content i.material-icons {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue