Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/commit config from UI #1413

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Dashy",
"version": "2.1.1",
"version": "2.2.0",
"license": "MIT",
"main": "server",
"author": "Alicia Sykes <alicia@omg.lol> (https://aliciasykes.com)",
Expand Down
8 changes: 6 additions & 2 deletions src/components/InteractiveEditor/EditModeSaveMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@
<SaveLocallyIcon />
</Button>
<Button
:click="writeToDisk"
:click="CommitToGithub"
:disallow="!permissions.allowWriteToDisk"
v-tooltip="tooltip($t('interactive-editor.menu.save-disk-tooltip'))"
>
{{ $t('interactive-editor.menu.save-disk-btn') }}
Commit to Github
<!-- {{ $t('interactive-editor.menu.save-disk-btn') }} -->
<SaveToDiskIcon />
</Button>
<Button
Expand Down Expand Up @@ -174,6 +175,9 @@ export default {
writeToDisk() {
this.writeConfigToDisk(this.config);
},
CommitToGithub() {
this.CommitConfigToGithub(this.config);
},
},
};
</script>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Widgets/PublicHolidays.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ export default {
const formatType = (ht) => capitalize(ht.replaceAll('_', ' '));
holidays.forEach((holiday) => {
results.push({
name: holiday.name.filter(p => p.lang == this.options.lang)[0].text || holiday.name[0].text,
name: holiday.name.filter(p => p.lang === this.options.lang)[0].text
|| holiday.name[0].text,
date: makeDate(holiday.date),
type: formatType(holiday.holidayType),
observed: holiday.observedOn ? makeDate(holiday.observedOn) : '',
Expand Down
153 changes: 153 additions & 0 deletions src/mixins/ConfigSaving.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default {
const headers = { 'Content-Type': 'text/plain' };
const filename = isSubPag
? (this.$store.state.currentConfigInfo.confPath || '') : '';

const body = { config: yaml, timestamp: new Date(), filename };
const request = axios.post(endpoint, body, headers);
// 4. Make the request, and handle response
Expand All @@ -58,6 +59,158 @@ export default {
this.progress.end();
});
},
async CommitConfigToGithub(config) {
// 1. Get the config, and strip appConfig if is sub-page
const isSubPag = !!this.$store.state.currentConfigInfo;
const jsonConfig = config;
if (isSubPag) delete jsonConfig.appConfig;
// 2. Convert JSON into YAML
const yamlOptions = {};
const configFileYaml = jsYaml.dump(jsonConfig, yamlOptions);

const accessToken = '<YOUR_ACCESS_TOKEN>';
const repoName = 'Musubi42/dashy-commit-config-from-ui';
const filePath = 'public/conf.yml';

// 3. Prepare the request
const baseUrl = `https://api.github.com/repos/${repoName}`;
// const endpoint = `${baseUrl}${serviceEndpoints.save}`;
const headers = {
headers: {
Authorization: `token ${accessToken}`,
Accept: 'application/vnd.github.v3+json',
},
};

// Declare all the variables
let lastCommitSha = null;
let baseTreeSha = null;
let blobSha = null;
let treeSha = null;
let newCommitSha = null;
let referenceUpdated = null;

// Step 1: Get the last commit sha
try {
const endpointLastCommitSha = `${baseUrl}/git/refs/heads/master`;
const requestLastCommitSha = await axios.get(endpointLastCommitSha, headers);

if (requestLastCommitSha.status !== 200) {
this.showToast(this.$t('config-editor.error-msg-cannot-save'), false);
return;
}

lastCommitSha = requestLastCommitSha.data.object.sha;
} catch (error) {
this.showToast(error, false);
ErrorHandler(`Failed to get last commit SHA. ${error}`);
}

// Step 2: Get the base tree SHA
try {
const endpointBaseTreeSha = `${baseUrl}/git/commits/${lastCommitSha}`;
const requestBaseTreeSha = await axios.get(endpointBaseTreeSha, headers);

if (requestBaseTreeSha.status !== 200) {
this.showToast(this.$t('config-editor.error-msg-cannot-save'), false);
return;
}

baseTreeSha = requestBaseTreeSha.data.tree.sha;
} catch (error) {
this.showToast(error, false);
ErrorHandler(`Failed to get base tree SHA. ${error}`);
}

// Step 3: Create a blob
try {
const endpointCreateBlob = `${baseUrl}/git/blobs`;
const blobData = { content: configFileYaml, encoding: 'utf-8' };
const requestCreateBlob = await axios.post(endpointCreateBlob, blobData, headers);

if (requestCreateBlob.status !== 201) {
this.showToast(this.$t('config-editor.error-msg-cannot-save'), false);
return;
}

blobSha = requestCreateBlob.data.sha;
} catch (error) {
this.showToast(error, false);
ErrorHandler(`Failed to create blob. ${error}`);
}

// Step 4: Create a tree
try {
const endpointCreateTree = `${baseUrl}/git/trees`;
const treeData = {
base_tree: baseTreeSha,
tree: [
{
path: filePath, mode: '100644', type: 'blob', sha: blobSha,
},
],
};

const requestCreateTree = await axios.post(endpointCreateTree, treeData, headers);

if (requestCreateTree.status !== 201) {
this.showToast(this.$t('config-editor.error-msg-cannot-save'), false);
return;
}

treeSha = requestCreateTree.data.sha;
} catch (error) {
this.showToast(error, false);
ErrorHandler(`Failed to create blob. ${error}`);
}

// Step 5: Create a commit
try {
const endpointCreateCommit = `${baseUrl}/git/commits`;
const commitData = {
message: 'Add file via API',
tree: treeSha,
parents: [lastCommitSha],
};
const requestCreateCommit = await axios.post(endpointCreateCommit, commitData, headers);

if (requestCreateCommit.status !== 201) {
this.showToast(this.$t('config-editor.error-msg-cannot-save'), false);
return;
}

newCommitSha = requestCreateCommit.data.sha;
} catch (error) {
this.showToast(error, false);
ErrorHandler(`Failed to create commit. ${error}`);
}

// // Step 6: Update the reference
try {
const endpointUpdateReference = `${baseUrl}/git/refs/heads/master`;
const refData = { sha: newCommitSha };
const requestCreateCommit = await axios.patch(endpointUpdateReference, refData, headers);

if (requestCreateCommit.status !== 200) {
this.showToast(this.$t('config-editor.error-msg-cannot-save'), false);
return;
}

referenceUpdated = requestCreateCommit.data;
} catch (error) {
this.showToast(error, false);
ErrorHandler(`Failed to update reference. ${error}`);
}

if (referenceUpdated) {
this.carefullyClearLocalStorage();
this.showToast(`Config has been commit to ${repoName}/${filePath}`, true);
} else {
this.showToast(this.$t('config-editor.error-msg-cannot-save'), false);
}

InfoHandler(`Config has been commit to ${filePath}`, referenceUpdated);
},
saveConfigLocally(config) {
if (!this.permissions.allowSaveLocally) {
ErrorHandler('Unable to save changes locally, this feature has been disabled');
Expand Down