Skip to content

Commit

Permalink
Merge pull request #210 from multinet-app/upload-status
Browse files Browse the repository at this point in the history
Show upload status in workspace detail view
  • Loading branch information
JackWilb authored Dec 14, 2021
2 parents a6a0d55 + 39882a8 commit 521773a
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 78 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"direct-vuex": "^0.10.4",
"lodash": "^4.17.21",
"material-design-icons-iconfont": "^5.0.1",
"multinet": "0.21.4",
"multinet": "0.21.5",
"papaparse": "^5.3.0",
"vue": "^2.6.10",
"vue-async-computed": "^3.8.2",
Expand Down
10 changes: 10 additions & 0 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { SingleUserWorkspacePermissionSpec, UserSpec } from 'multinet';
import api from '@/api';
import oauthClient from '@/oauth';
import { RoleLevel } from '@/utils/permissions';
import { Upload } from '@/types';

Vue.use(Vuex);

Expand All @@ -21,6 +22,7 @@ export interface State {
currentWorkspace: WorkspaceState | null;
userInfo: UserSpec | null;
currentWorkspacePermission: SingleUserWorkspacePermissionSpec | null;
uploads: Upload[];
}

const {
Expand All @@ -35,6 +37,7 @@ const {
currentWorkspace: null,
userInfo: null,
currentWorkspacePermission: null,
uploads: [],
} as State,
getters: {
tables(state: State, getters): string[] {
Expand Down Expand Up @@ -100,6 +103,10 @@ const {
setPermissionInfo(state, permissionInfo: SingleUserWorkspacePermissionSpec | null) {
state.currentWorkspacePermission = permissionInfo;
},

setUploads(state, uploads: Upload[]) {
state.uploads = uploads;
},
},
actions: {
async fetchWorkspaces(context) {
Expand All @@ -118,6 +125,9 @@ const {
const nodeTables = tables.filter((table) => table.edge === false);
const edgeTables = tables.filter((table) => table.edge === true);

const uploads = await api.uploads(workspace);
commit.setUploads(uploads.results);

const permissionsInfo = await api.getCurrentUserWorkspacePermissions(workspace);
commit.setPermissionInfo(permissionsInfo);

Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,9 @@ export interface NetworkFileType extends FileType{
export interface FileTypeTable {
[key: string]: FileType;
}

export interface Upload {
blob: string;
status: string;
data_type: string;
}
174 changes: 101 additions & 73 deletions src/views/WorkspaceDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,39 @@
<workspace-option-menu :workspace="workspace" />
</v-app-bar>

<v-layout
wrap
<v-row
v-for="upload in uploads"
:key="upload.id"
>
<v-flex
md6
px-5
py-3
<v-col
cols="12"
class="ma-0"
>
<v-alert
border="left"
color="blue"
type="info"
class="mb-0"
>
<v-row align="center">
<v-col class="grow">
Uploading: {{ upload.blob.substring(upload.blob.indexOf('/') + 1) }}
</v-col>
<v-col class="shrink">
<v-progress-circular
indeterminate
color="white"
size="26"
/>
</v-col>
</v-row>
</v-alert>
</v-col>
</v-row>
<v-row class="ma-0">
<v-col
cols="6"
class="px-5"
>
<v-card
color="transparent"
Expand All @@ -104,12 +130,11 @@
:loading="loading"
/>
</v-card>
</v-flex>
</v-col>

<v-flex
md6
px-5
py-3
<v-col
cols="6"
class="px-5"
>
<v-card
color="transparent"
Expand All @@ -122,14 +147,16 @@
:loading="loading"
/>
</v-card>
</v-flex>
</v-layout>
</v-col>
</v-row>
</v-main>
</v-container>
</template>

<script lang="ts">
import Vue, { PropType } from 'vue';
import {
defineComponent, ref, PropType, computed, watch,
} from '@vue/composition-api';
import api from '@/api';
import TablePanel from '@/components/TablePanel.vue';
Expand All @@ -143,107 +170,108 @@ const workspaceNameRules: Array<(x: string) => string|boolean> = [
(x: string) => !surroundingWhitespace.test(x) || 'Workspace name cannot begin or end with whitespace',
];
export default Vue.extend({
export default defineComponent({
name: 'WorkspaceDetail',
components: {
TablePanel,
NetworkPanel,
WorkspaceOptionMenu,
},
props: {
workspace: {
type: String as PropType<string>,
required: true,
},
},
data() {
return {
localWorkspace: null as string | null,
editing: false,
requestError: null as string | null,
loading: false,
};
},
computed: {
nodeTables: () => store.getters.nodeTables,
edgeTables: () => store.getters.edgeTables,
tables: () => store.getters.tables,
networks: () => store.getters.networks,
setup(props, ctx) {
const router = ctx.root.$router;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
nameErrorMessages(this: any): string[] {
const { requestError } = this;
const localWorkspace = ref<string | null>(null);
const editing = ref(false);
const requestError = ref<string | null>(null);
const loading = ref(false);
const nodeTables = computed(() => store.getters.nodeTables);
const edgeTables = computed(() => store.getters.edgeTables);
const tables = computed(() => store.getters.tables);
const networks = computed(() => store.getters.networks);
const uploads = computed(() => store.state.uploads.filter((upload) => upload.status !== 'FINISHED'));
const nameErrorMessages = computed(() => {
const errors = [
...workspaceNameRules.map((rule) => rule(this.localWorkspace as string)),
...workspaceNameRules.map((rule) => rule(localWorkspace.value as string)),
requestError,
];
return errors.filter((res): res is string => typeof res === 'string');
},
},
watch: {
workspace() {
this.update();
},
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
localWorkspace(this: any) {
// Once the user types, clears the error returned on sending the rename API call.
this.requestError = null;
},
},
created() {
this.update();
},
methods: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
cancelRename(this: any) {
this.requestError = null;
this.localWorkspace = this.workspace;
this.editing = false;
},
function cancelRename() {
requestError.value = null;
localWorkspace.value = props.workspace;
editing.value = false;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async renameWorkspace(this: any) {
if (this.nameErrorMessages.length) {
async function renameWorkspace() {
if (nameErrorMessages.value.length) {
return;
}
if (this.localWorkspace === this.workspace) {
this.editing = false;
if (localWorkspace.value === props.workspace) {
editing.value = false;
return;
}
if (this.localWorkspace !== null) {
if (localWorkspace.value !== null) {
try {
const { name } = await api.renameWorkspace(this.workspace, this.localWorkspace);
this.$router.push(`/workspaces/${name}`);
this.editing = false;
this.requestError = null;
const { name } = await api.renameWorkspace(props.workspace, localWorkspace.value);
router.push(`/workspaces/${name}`);
editing.value = false;
requestError.value = null;
store.dispatch.fetchWorkspaces();
} catch (err) {
if (err.response.status === 409) {
this.requestError = 'A workspace by that name already exists';
requestError.value = 'A workspace by that name already exists';
} else {
this.requestError = `${Object.values(err.response.data).flat()[0]}`;
requestError.value = `${Object.values(err.response.data).flat()[0]}`;
}
}
}
},
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async update(this: any) {
this.loading = true;
async function update(this: any) {
loading.value = true;
this.localWorkspace = this.workspace;
await store.dispatch.fetchWorkspace(this.workspace);
this.loading = false;
},
},
localWorkspace.value = props.workspace;
await store.dispatch.fetchWorkspace(props.workspace);
loading.value = false;
}
watch(() => props.workspace, () => update());
watch(localWorkspace, () => { requestError.value = null; });
update();
return {
editing,
loading,
networks,
nodeTables,
edgeTables,
tables,
cancelRename,
renameWorkspace,
nameErrorMessages,
localWorkspace,
uploads,
};
},
});
</script>

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6162,10 +6162,10 @@ multimatch@^2.1.0:
arrify "^1.0.0"
minimatch "^3.0.0"

[email protected].4:
version "0.21.4"
resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.21.4.tgz#9b9015fdeebd245800833db21b8f8e6d81aa351d"
integrity sha512-lYdj11yi5PJblDMg+T1fTih/2RMgIljYoWhpKElUNOdwPCHmc4Z1wFAd7Yo3nf1qKic2qlx0ac45XTcswnl05g==
[email protected].5:
version "0.21.5"
resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.21.5.tgz#417253d5dd91682c1efc076296261894432daeba"
integrity sha512-K76wN//AF/0ueCSB4eL/7pcf8mfmDmaa5lM8V+LL6E1kkrf1ucjBeFVhSrqcQ0HrtACawOmk7DEz6XZ6W4Na7w==
dependencies:
axios "^0.21.1"
django-s3-file-field "^0.1.2"
Expand Down

0 comments on commit 521773a

Please sign in to comment.