Add support for non-existent files being edited

This commit is contained in:
Dane Everitt 2019-05-27 16:30:23 -07:00
parent bfdc1f766b
commit 06337e45d8
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
4 changed files with 84 additions and 28 deletions

View file

@ -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) {

View file

@ -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

View file

@ -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 {