Files
skyline-console/src/pages/compute/containers/Image/actions/ManageMetadata.jsx
Jingwei.Zhang 166f8b5ed7 fix: Fix folder name
Fix folder name to avoid docker build failure

Change-Id: I810e948e46698f4acd92b1c3da7e7b200fa8a7dc
2021-06-24 11:49:24 +08:00

263 lines
6.3 KiB
JavaScript

// Copyright 2021 99cloud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { inject, observer } from 'mobx-react';
import globalImageStore from 'stores/glance/image';
import { ModalAction } from 'containers/Action';
import KeyValueInput from 'components/FormItem/KeyValueInput';
import { MetadataStore } from 'stores/glance/metadata';
import { isEmpty, has } from 'lodash';
import { isOwner } from 'resources/image';
@inject('rootStore')
@observer
export default class ManageMetadata extends ModalAction {
static id = 'ManageMetadata';
static title = t('Manage Metadata');
init() {
this.store = globalImageStore;
this.metadataStore = new MetadataStore();
this.getMetadatas();
}
get name() {
return t('Manage host');
}
static get modalSize() {
return 'large';
}
getModalSize() {
return 'large';
}
get wrapperCol() {
return {
xs: { span: 18 },
sm: { span: 20 },
};
}
static policy = 'modify_image';
static allowed = (item, containerProps) => {
const { isAdminPage } = containerProps;
return Promise.resolve(isOwner(item) || isAdminPage);
};
async getMetadatas() {
const resouceType = 'OS::Glance::Image';
await this.metadataStore.fetchList({
manage: true,
resource_types: resouceType,
});
this.updateDefaultValue();
}
get metadatas() {
return this.metadataStore.list.data || [];
}
getItemMetadata() {
const {
container_format,
disk_format,
id,
min_disk,
min_ram,
name,
protected: imageProtected,
tags,
visibility,
owner,
created_at,
is_public,
updated_at,
status,
locations,
file,
size,
image_type,
self,
project_name,
virtual_size,
...rest
} = this.item;
return rest;
}
checkKeyInSystem = (key) => {
const metadata = this.metadatas.find((it) => {
const { detail: { properties = {} } = {} } = it;
return Object.keys(properties).indexOf(key) >= 0;
});
return !!metadata;
};
parseExistMetadatas() {
const customs = [];
const systems = {};
if (this.metadatas.length > 0) {
const metadata = this.getItemMetadata();
Object.keys(metadata).forEach((key) => {
if (this.checkKeyInSystem(key)) {
systems[key] = metadata[key];
} else {
customs.push({
index: customs.length,
value: { key, value: metadata[key] },
});
}
});
}
return {
customs,
systems,
};
}
get defaultValue() {
const { name } = this.item;
const { customs, systems } = this.parseExistMetadatas();
const value = {
name,
customs,
systems,
};
return value;
}
checkCustoms = (values) => {
if (isEmpty(values)) {
return true;
}
const item = values.find((it) => {
const { key, value } = it.value || {};
return !key || value === undefined || value === null;
});
return !item;
};
hasNoValue = (values) => {
const item = Object.keys(values).find((it) => values[it] === undefined);
return !!item;
};
get formItems() {
return [
{
name: 'name',
label: t('Name'),
type: 'label',
iconType: 'aggregate',
},
{
name: 'customs',
label: t('Custom Metadata'),
type: 'add-select',
itemComponent: KeyValueInput,
addText: t('Add Custom Metadata'),
validator: (rule, value) => {
if (!this.checkCustoms(value)) {
// eslint-disable-next-line prefer-promise-reject-errors
return Promise.reject(t('Please enter complete key value!'));
}
return Promise.resolve();
},
},
{
name: 'systems',
label: t('Metadata'),
type: 'metadata-transfer',
metadatas: this.metadatas,
validator: (rule, value) => {
if (this.hasNoValue(value)) {
// eslint-disable-next-line prefer-promise-reject-errors
return Promise.reject(t('Please input value'));
}
return Promise.resolve();
},
},
];
}
onSubmit = (values) => {
const { customs: oldCumtoms, systems: oldSystems } =
this.parseExistMetadatas();
const { customs, systems } = values;
const adds = [];
const removes = [];
const replaces = [];
customs.forEach((it) => {
const { key, value } = it.value || {};
const oldItem = oldCumtoms.find((c) => c.value.key === key);
if (!oldItem) {
adds.push(it.value);
} else if (oldItem.value.value !== value) {
replaces.push(it.value);
}
});
Object.keys(systems).forEach((key) => {
const item = {
key,
value: systems[key],
};
if (!has(oldSystems, key)) {
adds.push(item);
} else if (systems[key] !== oldSystems[key]) {
replaces.push(item);
}
});
oldCumtoms.forEach((it) => {
const item = customs.find((custom) => custom.value.key === it.value.key);
if (!item) {
removes.push(it.value.key);
}
});
Object.keys(oldSystems).forEach((key) => {
if (!has(systems, key)) {
removes.push(key);
}
});
const changeValues = [];
adds.forEach((it) => {
changeValues.push({
op: 'add',
path: `/${it.key}`,
value: it.value,
});
});
replaces.forEach((it) => {
changeValues.push({
op: 'replace',
path: `/${it.key}`,
value: it.value,
});
});
removes.forEach((it) => {
changeValues.push({
op: 'remove',
path: `/${it}`,
});
});
if (changeValues.length === 0) {
return Promise.resolve();
}
return this.store.update({ id: this.item.id }, changeValues);
};
}