skyline/src/stores/swift/object.js
Jingwei.Zhang ace9ca0ece feat: Add swift
1. Add swift container list page
2. Add swift container object list page
3. Add create/delete container
4. Add create/edit/delete/copy/cut/paste/rename file
5. Add create/delete folder

Change-Id: Id4a675688b4a8beb40921173d7637e331a77b77e
2021-12-01 16:20:02 +08:00

308 lines
7.4 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 { action, observable } from 'mobx';
import client from 'client';
import { getArrayBuffer } from 'utils/file';
import Base from '../base';
export class ObjectStore extends Base {
@observable
container = null;
@observable
data = [];
@observable
hasNext = false;
@observable
copiedFiles = [];
@observable
hasCopy = false;
@observable
isCopy = true;
get client() {
return client.swift.container.object;
}
get containerClient() {
return client.swift.container;
}
get listResponseKey() {
return '';
}
get listFilterByProject() {
return false;
}
async listFetchByClient(params, originParams) {
const { folder, container } = originParams;
const { path } = params;
const result = await this.client.list(container, params);
this.container = {
name: container,
folder,
path,
hasCopy: this.copiedFiles.length > 0,
};
return result;
}
get paramsFunc() {
return (params) => {
const { current, container, folder, search = '', ...rest } = params;
return {
path: `${folder}${search}`,
delimiter: `/`,
...rest,
};
};
}
getShortName = (name, folder) => name.substring((folder || '').length);
getItemType = (it) => {
if (it.subdir) {
return 'folder';
}
const { name } = it;
if (name[name.length - 1] === '/') {
return 'folder';
}
return 'file';
};
async listDidFetch(items, _, filters) {
if (items.length === 0) {
return items;
}
const { container } = filters;
const needFetch = items.some((it) => it.subdir);
if (!needFetch) {
return this.updateData(items);
}
const result = await this.client.list(container);
const newItems = items.map((it) => {
if (it.subdir) {
const item = result.find((r) => r.name === it.subdir) || {};
return {
...it,
...item,
};
}
return { ...it };
});
return this.updateData(newItems);
}
async detailFetchByClient(resourceParams) {
const { container, name } = resourceParams;
const result = await this.containerClient.showObjectMetadata(
container,
name
);
const { headers = {} } = result;
const data = {
timestamp: headers['x-timestamp'],
contentType: headers['content-type'],
etag: headers.etag,
size: headers['content-length'],
originFileName: headers['x-object-meta-orig-filename'],
};
return data;
}
@action
updateData = (items) => {
const { name, path, folder, hasCopy } = this.container || {};
return items.map((it) => {
return {
...it,
container: name,
path,
folder,
type: this.getItemType(it),
hasCopy,
shortName: it.name && this.getShortName(it.name, folder),
};
});
};
@action
async createFolder(container, data) {
const { folder_name, dest_folder = '' } = data;
const name = `${dest_folder}${folder_name}/`;
await this.checkName(container, name);
return this.submitting(this.containerClient.createFolder(container, name));
}
@action
async createFile(container, data, config = {}) {
const { file, dest_folder = '' } = data;
const name = `${dest_folder}${file.name}`;
await this.checkName(container, name);
const headers = {
'X-Object-Meta-Orig-Filename': encodeURIComponent(file.name),
'Content-Length': file.size,
'Content-Type': file.type,
};
const content = await getArrayBuffer(file);
return this.submitting(
this.containerClient.uploadFile(container, name, content, {
headers,
...config,
})
);
}
@action
async updateFile(container, file, name, config = {}) {
const headers = {
'X-Object-Meta-Orig-Filename': encodeURIComponent(file.name),
'Content-Length': file.size,
'Content-Type': file.type,
};
const content = await getArrayBuffer(file);
return this.submitting(
this.containerClient.uploadFile(container, name, content, {
headers,
...config,
})
);
}
@action
async rename(container, name, newname) {
this.isSubmitting = true;
await this.checkName(container, newname);
await this.containerClient.copy(container, name, container, newname);
return this.delete({ container, name });
}
@action
async downloadFile({ container, name }) {
return this.client.show(container, name, null, {
responseType: 'blob',
});
}
@action
delete = async ({ container, name }) => {
return this.submitting(this.client.delete(container, name));
};
@action
checkName = async (container, name) => {
try {
await this.containerClient.showObjectMetadata(container, name);
const err = {
response: {
data: t('An object with the same name already exists'),
},
};
return Promise.reject(err);
} catch (e) {
return true;
}
};
@action
copyFiles = async (files) => {
this.copiedFiles = files;
this.hasCopy = files.length > 0;
this.isCopy = true;
return Promise.resolve();
};
@action
cutFiles = async (files) => {
this.copiedFiles = files;
this.hasCopy = files.length > 0;
this.isCopy = false;
return Promise.resolve();
};
@action
pasteFiles = async (folder) => {
if (this.copiedFiles.length === 0) {
return Promise.reject();
}
let realFolder = folder;
if (!folder) {
realFolder = {
container: this.container.name,
name: this.container.folder,
};
}
if (this.isCopy) {
return this.pasteObjects(realFolder);
}
return this.moveObjects(realFolder);
};
@action
async pasteObjects(folder) {
const { container: toContainer, name } = folder;
const { container: fromContainer } = this.copiedFiles[0];
await Promise.all(
this.copiedFiles.map((it) => {
const { shortName, name: fromName } = it;
const toName = `${name}${shortName}`;
return this.containerClient.copy(
fromContainer,
fromName,
toContainer,
toName
);
})
);
return Promise.resolve();
}
@action
async moveObjects(folder) {
await this.pasteObjects(folder);
const { container: originContainer } = this.copiedFiles[0];
await Promise.all(
this.copiedFiles.map((it) => {
const { name: fileName } = it;
return this.client.delete(originContainer, fileName);
})
);
this.copiedFiles = [];
this.hasCopy = false;
return Promise.resolve();
}
@action
clearData(listUnmount) {
this.list.reset();
if (!listUnmount) {
this.copiedFiles = [];
this.hasCopy = false;
this.container = null;
}
}
}
const globalObjectStore = new ObjectStore();
export default globalObjectStore;