diff --git a/package.json b/package.json index 689fd2cc653a272015580fbfdc97066d619996d0..0f651147bbd25370ac2b2b62a1387558fd858d4a 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "autwh": "0.0.1", "bcryptjs": "2.4.3", "body-parser": "1.18.2", + "bootstrap-vue": "^2.0.0-rc.1", "cache-loader": "1.2.0", "cafy": "3.2.1", "chai": "4.1.2", diff --git a/src/web/app/dev/script.ts b/src/web/app/dev/script.ts index 757bfca490cd0b511748b4233f78899222247743..2f4a16fab1e0be9cf17fcf949b0a679b50b7b9c5 100644 --- a/src/web/app/dev/script.ts +++ b/src/web/app/dev/script.ts @@ -2,6 +2,11 @@ * Developer Center */ +import Vue from 'vue'; +import BootstrapVue from 'bootstrap-vue'; +import 'bootstrap/dist/css/bootstrap.css'; +import 'bootstrap-vue/dist/bootstrap-vue.css'; + // Style import './style.styl'; @@ -11,6 +16,11 @@ import Index from './views/index.vue'; import Apps from './views/apps.vue'; import AppNew from './views/new-app.vue'; import App from './views/app.vue'; +import ui from './views/ui.vue'; + +Vue.use(BootstrapVue); + +Vue.component('mk-ui', ui); /** * init @@ -22,7 +32,7 @@ init(launch => { // Routing app.$router.addRoutes([ { path: '/', component: Index }, - { path: '/app', component: Apps }, + { path: '/apps', component: Apps }, { path: '/app/new', component: AppNew }, { path: '/app/:id', component: App }, ]); diff --git a/src/web/app/dev/style.styl b/src/web/app/dev/style.styl index cdbcb0e2615b0f773f21dc6f7cc467d5f6afdbc2..e635897b170fee1f653983f1676d1d960350d35f 100644 --- a/src/web/app/dev/style.styl +++ b/src/web/app/dev/style.styl @@ -1,5 +1,10 @@ @import "../app" @import "../reset" +// Bootstrapã®ãƒ‡ã‚¶ã‚¤ãƒ³ã‚’å´©ã™ã®ã§: +* + position initial + background-clip initial !important + html background-color #fff diff --git a/src/web/app/dev/views/app.vue b/src/web/app/dev/views/app.vue index 9eddabbec22560f8b6df069db7dd6099c924da29..2c2a3c83ce7834eae7b63dd2313d35f5146befdb 100644 --- a/src/web/app/dev/views/app.vue +++ b/src/web/app/dev/views/app.vue @@ -1,16 +1,12 @@ <template> -<div> +<mk-ui> <p v-if="fetching">èªã¿è¾¼ã¿ä¸</p> - <main v-if="!fetching"> - <header> - <h1>{{ app.name }}</h1> - </header> - <div class="body"> - <p>App Secret</p> - <input :value="app.secret" readonly/> - </div> - </main> -</div> + <b-card v-if="!fetching" :header="app.name"> + <b-form-group label="App Secret"> + <b-input :value="app.secret" readonly/> + </b-form-group> + </b-card> +</mk-ui> </template> <script lang="ts"> diff --git a/src/web/app/dev/views/apps.vue b/src/web/app/dev/views/apps.vue index 42b4abc9b848a40c263bfba346cf90d129ab3570..7e0b107a3079c6ead31086bb2a0c32b22ace5925 100644 --- a/src/web/app/dev/views/apps.vue +++ b/src/web/app/dev/views/apps.vue @@ -1,21 +1,21 @@ <template> -<div> - <h1>アプリを管ç†</h1> - <router-link to="/app/new">アプリ作æˆ</router-link> - <div class="apps"> - <p v-if="fetching">èªã¿è¾¼ã¿ä¸</p> - <template v-if="!fetching"> - <p v-if="apps.length == 0">アプリãªã—</p> - <ul v-else> - <li v-for="app in apps" :key="app.id"> - <router-link :to="`/app/${app.id}`"> - <p class="name">{{ app.name }}</p> - </router-link> - </li> - </ul> - </template> - </div> -</div> +<mk-ui> + <b-card header="アプリを管ç†"> + <b-button to="/app/new" variant="primary">アプリ作æˆ</b-button> + <hr> + <div class="apps"> + <p v-if="fetching">èªã¿è¾¼ã¿ä¸</p> + <template v-if="!fetching"> + <b-alert v-if="apps.length == 0">アプリãªã—</b-alert> + <b-list-group v-else> + <b-list-group-item v-for="app in apps" :key="app.id" :to="`/app/${app.id}`"> + {{ app.name }} + </b-list-group-item> + </b-list-group> + </template> + </div> + </b-card> +</mk-ui> </template> <script lang="ts"> diff --git a/src/web/app/dev/views/index.vue b/src/web/app/dev/views/index.vue index a8429a56ddc10df3413ded4d86768cde5c3720ec..3f572b390707f4842e97d05936309728854b56da 100644 --- a/src/web/app/dev/views/index.vue +++ b/src/web/app/dev/views/index.vue @@ -1,7 +1,7 @@ <template> -<div> - <router-link to="/app">アプリ</router-link> -</div> +<mk-ui> + <b-button to="/apps" variant="primary">アプリã®ç®¡ç†</b-button> +</mk-ui> </template> <script lang="ts"> diff --git a/src/web/app/dev/views/new-app.vue b/src/web/app/dev/views/new-app.vue index f2e5659a4e03f668de280a23cfd33ba20ccfd91c..344e8468f929b78288309d8c87c41c0c63380cbf 100644 --- a/src/web/app/dev/views/new-app.vue +++ b/src/web/app/dev/views/new-app.vue @@ -1,16 +1,12 @@ <template> -<div> - <form @submit="onSubmit" autocomplete="off"> - <section class="name"> - <label> - <p class="caption">アプリケーションå</p> - <input v-model="name" type="text" placeholder="ex) Misskey for iOS" autocomplete="off" required/> - </label> - </section> - <section class="nid"> - <label> - <p class="caption">Named ID</p> - <input v-model="nid" type="text" pattern="^[a-zA-Z0-9-]{3,30}$" placeholder="ex) misskey-for-ios" autocomplete="off" required/> +<mk-ui> + <b-card header="アプリケーションã®ä½œæˆ"> + <b-form @submit.prevent="onSubmit" autocomplete="off"> + <b-form-group label="アプリケーションå" description="ã‚ãªãŸã®ã‚¢ãƒ—リã®å称。"> + <b-form-input v-model="name" type="text" placeholder="ex) Misskey for iOS" autocomplete="off" required/> + </b-form-group> + <b-form-group label="ID" description="ã‚ãªãŸã®ã‚¢ãƒ—リã®ID。"> + <b-input v-model="nid" type="text" pattern="^[a-zA-Z0-9-]{3,30}$" placeholder="ex) misskey-for-ios" autocomplete="off" required/> <p class="info" v-if="nidState == 'wait'" style="color:#999">%fa:spinner .pulse .fw%確èªã—ã¦ã„ã¾ã™...</p> <p class="info" v-if="nidState == 'ok'" style="color:#3CB7B5">%fa:fw check%利用ã§ãã¾ã™</p> <p class="info" v-if="nidState == 'unavailable'" style="color:#FF1161">%fa:fw exclamation-triangle%æ—¢ã«åˆ©ç”¨ã•ã‚Œã¦ã„ã¾ã™</p> @@ -18,65 +14,34 @@ <p class="info" v-if="nidState == 'invalid-format'" style="color:#FF1161">%fa:fw exclamation-triangle%a~zã€A~Zã€0~9ã€-(ãƒã‚¤ãƒ•ãƒ³)ãŒä½¿ãˆã¾ã™</p> <p class="info" v-if="nidState == 'min-range'" style="color:#FF1161">%fa:fw exclamation-triangle%3æ–‡å—以上ã§ãŠé¡˜ã„ã—ã¾ã™ï¼</p> <p class="info" v-if="nidState == 'max-range'" style="color:#FF1161">%fa:fw exclamation-triangle%30æ–‡å—以内ã§ãŠé¡˜ã„ã—ã¾ã™</p> - </label> - </section> - <section class="description"> - <label> - <p class="caption">アプリã®æ¦‚è¦</p> - <textarea v-model="description" placeholder="ex) Misskey iOSクライアント。" autocomplete="off" required></textarea> - </label> - </section> - <section class="callback"> - <label> - <p class="caption">コールãƒãƒƒã‚¯URL (オプション)</p> - <input v-model="cb" type="url" placeholder="ex) https://your.app.example.com/callback.php" autocomplete="off"/> - </label> - </section> - <section class="permission"> - <p class="caption">権é™</p> - <div ref="permission"> - <label> - <input type="checkbox" value="account-read"/> - <p>アカウントã®æƒ…å ±ã‚’è¦‹ã‚‹ã€‚</p> - </label> - <label> - <input type="checkbox" value="account-write"/> - <p>アカウントã®æƒ…å ±ã‚’æ“作ã™ã‚‹ã€‚</p> - </label> - <label> - <input type="checkbox" value="post-write"/> - <p>投稿ã™ã‚‹ã€‚</p> - </label> - <label> - <input type="checkbox" value="reaction-write"/> - <p>リアクションã—ãŸã‚Šãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’ã‚ャンセルã™ã‚‹ã€‚</p> - </label> - <label> - <input type="checkbox" value="following-write"/> - <p>フォãƒãƒ¼ã—ãŸã‚Šãƒ•ã‚©ãƒãƒ¼è§£é™¤ã™ã‚‹ã€‚</p> - </label> - <label> - <input type="checkbox" value="drive-read"/> - <p>ドライブを見る。</p> - </label> - <label> - <input type="checkbox" value="drive-write"/> - <p>ドライブをæ“作ã™ã‚‹ã€‚</p> - </label> - <label> - <input type="checkbox" value="notification-read"/> - <p>通知を見る。</p> - </label> - <label> - <input type="checkbox" value="notification-write"/> - <p>通知をæ“作ã™ã‚‹ã€‚</p> - </label> - </div> - <p>%fa:exclamation-triangle%アプリ作æˆå¾Œã‚‚変更ã§ãã¾ã™ãŒã€æ–°ãŸãªæ¨©é™ã‚’付与ã™ã‚‹å ´åˆã€ãã®æ™‚点ã§é–¢é€£ä»˜ã‘られã¦ã„るユーザーã‚ーã¯ã™ã¹ã¦ç„¡åŠ¹ã«ãªã‚Šã¾ã™ã€‚</p> - </section> - <button type="submit">アプリ作æˆ</button> - </form> -</div> + </b-form-group> + <b-form-group label="アプリã®æ¦‚è¦" description="ã‚ãªãŸã®ã‚¢ãƒ—リã®ç°¡å˜ãªèª¬æ˜Žã‚„紹介。"> + <b-textarea v-model="description" placeholder="ex) Misskey iOSクライアント。" autocomplete="off" required></b-textarea> + </b-form-group> + <b-form-group label="コールãƒãƒƒã‚¯URL (オプション)" description="ユーザーãŒèªè¨¼ãƒ•ã‚©ãƒ¼ãƒ ã§èªè¨¼ã—ãŸéš›ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã™ã‚‹URLã‚’è¨å®šã§ãã¾ã™ã€‚"> + <b-input v-model="cb" type="url" placeholder="ex) https://your.app.example.com/callback.php" autocomplete="off"/> + </b-form-group> + <b-card header="権é™"> + <b-form-group description="ã“ã“ã§è¦æ±‚ã—ãŸæ©Ÿèƒ½ã ã‘ãŒAPIã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™ã€‚"> + <b-alert show variant="warning">%fa:exclamation-triangle%アプリ作æˆå¾Œã‚‚変更ã§ãã¾ã™ãŒã€æ–°ãŸãªæ¨©é™ã‚’付与ã™ã‚‹å ´åˆã€ãã®æ™‚点ã§é–¢é€£ä»˜ã‘られã¦ã„るユーザーã‚ーã¯ã™ã¹ã¦ç„¡åŠ¹ã«ãªã‚Šã¾ã™ã€‚</b-alert> + <b-form-checkbox-group v-model="permission" stacked> + <b-form-checkbox value="account-read">アカウントã®æƒ…å ±ã‚’è¦‹ã‚‹ã€‚</b-form-checkbox> + <b-form-checkbox value="account-write">アカウントã®æƒ…å ±ã‚’æ“作ã™ã‚‹ã€‚</b-form-checkbox> + <b-form-checkbox value="post-write">投稿ã™ã‚‹ã€‚</b-form-checkbox> + <b-form-checkbox value="reaction-write">リアクションã—ãŸã‚Šãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’ã‚ャンセルã™ã‚‹ã€‚</b-form-checkbox> + <b-form-checkbox value="following-write">フォãƒãƒ¼ã—ãŸã‚Šãƒ•ã‚©ãƒãƒ¼è§£é™¤ã™ã‚‹ã€‚</b-form-checkbox> + <b-form-checkbox value="drive-read">ドライブを見る。</b-form-checkbox> + <b-form-checkbox value="drive-write">ドライブをæ“作ã™ã‚‹ã€‚</b-form-checkbox> + <b-form-checkbox value="notification-read">通知を見る。</b-form-checkbox> + <b-form-checkbox value="notification-write">通知をæ“作ã™ã‚‹ã€‚</b-form-checkbox> + </b-form-checkbox-group> + </b-form-group> + </b-card> + <hr> + <b-button type="submit" variant="primary">アプリ作æˆ</b-button> + </b-form> + </b-card> +</mk-ui> </template> <script lang="ts"> @@ -88,7 +53,8 @@ export default Vue.extend({ nid: '', description: '', cb: '', - nidState: null + nidState: null, + permission: [] }; }, watch: { @@ -122,18 +88,12 @@ export default Vue.extend({ }, methods: { onSubmit() { - const permission = []; - - (this.$refs.permission as any).querySelectorAll('input').forEach(el => { - if (el.checked) permission.push(el.value); - }); - (this as any).api('app/create', { name: this.name, name_id: this.nid, description: this.description, callback_url: this.cb, - permission: permission + permission: this.permission }).then(() => { location.href = '/apps'; }).catch(() => { diff --git a/src/web/app/dev/views/ui.vue b/src/web/app/dev/views/ui.vue new file mode 100644 index 0000000000000000000000000000000000000000..4a0fcee635beb9e82b619c196fa0979720ae0414 --- /dev/null +++ b/src/web/app/dev/views/ui.vue @@ -0,0 +1,20 @@ +<template> +<div> + <b-navbar toggleable="md" type="dark" variant="info"> + <b-navbar-brand>Misskey Developers</b-navbar-brand> + <b-navbar-nav> + <b-nav-item to="/">Home</b-nav-item> + <b-nav-item to="/apps">Apps</b-nav-item> + </b-navbar-nav> + </b-navbar> + <main> + <slot></slot> + </main> +</div> +</template> + +<style lang="stylus" scoped> +main + padding 32px + max-width 700px +</style>