Add support for non-existent files being edited
This commit is contained in:
parent
bfdc1f766b
commit
06337e45d8
4 changed files with 84 additions and 28 deletions
|
@ -6,7 +6,24 @@
|
||||||
<div class="modal-close-icon" v-on:click="closeModal">
|
<div class="modal-close-icon" v-on:click="closeModal">
|
||||||
<Icon name="x" aria-label="Close modal" role="button"/>
|
<Icon name="x" aria-label="Close modal" role="button"/>
|
||||||
</div>
|
</div>
|
||||||
<MessageBox class="alert error mb-2" title="Error" :message="error" v-if="error"/>
|
<MessageBox class="alert error mb-4" title="Error" :message="error" v-if="error"/>
|
||||||
|
<div class="flex items-center mb-4 bg-white rounded p-2">
|
||||||
|
<div class="mx-2">
|
||||||
|
<label class="input-label mb-0" for="file-name-input">File name:</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="file_name"
|
||||||
|
class="input"
|
||||||
|
id="file-name-input"
|
||||||
|
:disabled="typeof file !== 'undefined'"
|
||||||
|
v-model="fileName"
|
||||||
|
v-validate="'required'"
|
||||||
|
/>
|
||||||
|
<p class="input-help error" v-show="errors.has('file_name')">{{ errors.first('file_name') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="editor"></div>
|
<div id="editor"></div>
|
||||||
<div class="flex mt-4 bg-white rounded p-2">
|
<div class="flex mt-4 bg-white rounded p-2">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
|
@ -46,6 +63,7 @@
|
||||||
file?: DirectoryContentObject,
|
file?: DirectoryContentObject,
|
||||||
serverUuid?: string,
|
serverUuid?: string,
|
||||||
fm?: FileManagerState,
|
fm?: FileManagerState,
|
||||||
|
fileName?: string,
|
||||||
error: string | null,
|
error: string | null,
|
||||||
editor: Ace.Editor | null,
|
editor: Ace.Editor | null,
|
||||||
isVisible: boolean,
|
isVisible: boolean,
|
||||||
|
@ -58,6 +76,8 @@
|
||||||
editor: null,
|
editor: null,
|
||||||
isVisible: false,
|
isVisible: false,
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
|
file: undefined,
|
||||||
|
fileName: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
|
@ -101,6 +121,8 @@
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.isVisible = true;
|
this.isVisible = true;
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
this.fileName = file ? file.name : undefined;
|
||||||
|
this.errors.clear();
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.editor = Ace.edit('editor');
|
this.editor = Ace.edit('editor');
|
||||||
|
@ -120,13 +142,36 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
fileName: function (newValue?: string, oldValue?: string) {
|
||||||
|
if (newValue === oldValue || !newValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateFileLanguageFromName(newValue);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
submit: function () {
|
submit: function () {
|
||||||
|
if (!this.file && (!this.fileName || this.fileName.length === 0)) {
|
||||||
|
this.error = 'You must provide a file name before saving.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
const content = this.editor!.getValue();
|
const content = this.editor!.getValue();
|
||||||
|
|
||||||
writeFileContents(this.serverUuid!, join(this.fm!.currentDirectory, this.file!.name), content)
|
writeFileContents(this.serverUuid!, join(this.fm!.currentDirectory, this.fileName!), content)
|
||||||
.then(() => this.error = null)
|
.then(() => {
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
// @todo come up with a more graceful solution here
|
||||||
|
if (!this.file) {
|
||||||
|
this.$emit('refresh');
|
||||||
|
this.closeModal();
|
||||||
|
}
|
||||||
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
this.error = httpErrorToHuman(error);
|
this.error = httpErrorToHuman(error);
|
||||||
|
@ -147,12 +192,19 @@
|
||||||
editor.$blockScrolling = Infinity;
|
editor.$blockScrolling = Infinity;
|
||||||
editor.setValue(contents, 1);
|
editor.setValue(contents, 1);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => this.updateFileLanguageFromName(file.name))
|
||||||
// Set the correct MIME type on the editor for the user.
|
.then(() => resolve())
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
updateFileLanguageFromName: function (name: string) {
|
||||||
const modelist = Ace.acequire('ace/ext/modelist');
|
const modelist = Ace.acequire('ace/ext/modelist');
|
||||||
if (modelist) {
|
if (!modelist || !this.editor) {
|
||||||
const mode = modelist.getModeForPath(file.name).mode || 'ace/mode/text';
|
return;
|
||||||
editor.getSession().setMode(mode);
|
}
|
||||||
|
|
||||||
|
const mode = modelist.getModeForPath(name).mode || 'ace/mode/text';
|
||||||
|
|
||||||
const parts = mode.split('/');
|
const parts = mode.split('/');
|
||||||
const element = (this.$refs.fileLanguageSelector as HTMLSelectElement | null);
|
const element = (this.$refs.fileLanguageSelector as HTMLSelectElement | null);
|
||||||
|
@ -161,13 +213,9 @@
|
||||||
const index = this.supportedTypes.findIndex(value => value.type === parts[parts.length - 1]);
|
const index = this.supportedTypes.findIndex(value => value.type === parts[parts.length - 1]);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
element.selectedIndex = index;
|
element.selectedIndex = index;
|
||||||
|
this.editor.getSession().setMode(mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(() => resolve())
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updateFileLanguage: function (e: MouseEvent) {
|
updateFileLanguage: function (e: MouseEvent) {
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CreateFolderModal v-on:created="directoryCreated"/>
|
<CreateFolderModal v-on:created="directoryCreated"/>
|
||||||
<EditFileModal/>
|
<EditFileModal v-on:refresh="listDirectory"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -65,6 +65,10 @@ input[type=number] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input:disabled {
|
||||||
|
@apply .bg-neutral-100 .border-neutral-200;
|
||||||
|
}
|
||||||
|
|
||||||
select:not(.appearance-none) {
|
select:not(.appearance-none) {
|
||||||
@apply .outline-none .appearance-none .block .bg-white .border .border-neutral-200 .text-neutral-400 .p-3 .pr-8 rounded;
|
@apply .outline-none .appearance-none .block .bg-white .border .border-neutral-200 .text-neutral-400 .p-3 .pr-8 rounded;
|
||||||
transition: border-color 150ms linear, color 150ms linear;
|
transition: border-color 150ms linear, color 150ms linear;
|
||||||
|
@ -86,7 +90,11 @@ select:not(.appearance-none) {
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-label {
|
.input-label {
|
||||||
@apply .block .uppercase .tracking-wide .text-neutral-800 .text-xs .font-bold .mb-2;
|
@apply .block .uppercase .tracking-wide .text-neutral-800 .text-xs .font-bold;
|
||||||
|
|
||||||
|
&:not(.mb-0) {
|
||||||
|
@apply .mb-2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-help {
|
.input-help {
|
||||||
|
|
Loading…
Reference in a new issue