为了账号安全,请及时绑定邮箱和手机立即绑定

SwitchFlow:用你的DevCycle账户变量来切换原型中的UI功能。还能导出或下载结果。

这是提交给DevCycle Feature Flag Challenge:功能标志趣味屋

我建造的东西

这是我乐于构建的东西,无论结果如何,我都打算将其发展成为一个完整的SaaS,开辟web开发的新领域——UI功能标志技术。

问题描述:特性标志控制的UI界面

在 React 中进行网页组件的条件渲染是一回事,直接利用条件渲染功能设计 UI 并查看结果又是另一回事。

在代码编辑器里构建原型和网页用户界面,保存后在浏览器中查看结果就已经很难了,更别说还得做条件渲染。

由于缺少简单的保存功能和不完善的条件渲染支持,使用浏览器的开发工具直接编辑节点和样式以及编写脚本的更好方法受到了限制。

进入SwitchFlow - 一个基于网页的快速原型工具,它是在现有基础上进行改进,而不是重新发明轮子。

SwitchFlow的界面

  • 使用现有的 DevCycle 账户通过其 API 构建带有功能标志的 UI,或者创建、使用和存储功能标志。
  • 高效快速地预览更改
  • 无需登录账户即可保存并恢复进度
  • 直接粘贴完整的 HTML 标记到 DOM
  • 导入现有的 HTML 来快速启动设计过程
  • 基本的 DOM 操作,如批量克隆、变异、遍历,以及使用 DOM 变异方法和存储节点

它主要是给开发者用的,但普通用户也可以使用其UI功能标记服务。

示例

链接地址

https://switch-flow.vercel.app/

截图 (shètú)

网页应用的导入导出

如图所示,进出口部分

适用于8px及以上设计的动态布局网格

动态布局图 例如,这可以用于创建灵活的界面布局。

UI功能标志的初始页面

初始画面
这是初始画面

提供获取和使用授权令牌的 API 密钥

提供一下详细信息吧

通过API加载的各种变量和特性

UI 加载标志

在项目中选好环境后的用户界面

选择环境后显示的用户界面

选择要标记的元素,后

选中要切换的元素后,如下图所示

导出页面并应用UI标记以进行预览。

如上图所示,与上面的图片相比,可以看出,它的界面中有一些部分已经关闭了。

我的编程 GitHub logo ogbotemi-2000 的 GitHub 页面 / 项目 switch-flow

这是一个由 ogbotemi-2000 创建的 GitHub 项目,名为 switch-flow。

一个具有新UI功能标志的快速原型设计的灵活空间。

SwitchFlow

一个基于网页的快速原型制作工具,它利用来自不同来源的标记拼凑在一起,进行编辑和保存。它的目的是使元素的快速修改成为可能。它直接在UI原型中实现了“UI功能标志”这一出色想法,可以在UI中开启或关闭某些部分。

虽然它对开发者更友好,一般用户也可以轻松使用其界面的标志功能。

UI上的功能开关

它可以支持通过 API 使用 clientclient secret 密钥来连接 DevCycle 账户,并获取定义的所有变量。

  • 特性:及其可能存在的变体
  • 项目及其每个环境 - 测试、开发、生产

该应用是围绕DevCycle API构建的,为参加DevCycle 功能标志挑战挑战。因此,自定义本地标志的支持并未被优先考虑,而将在挑战结束后实现该功能。

查看 GitHub 上的页面:https://github.com/ogbotemi-2000/switch-flow

我的 DevCycle 体验(DevCycle 是一个特定的产品或服务名称)

因为 API 文档里少了关键信息,所以推迟了。

我因为没有很快意识到如何与DevCycle API沟通而耽误了好多时间,因为缺少了一个将用户账户认证与API操作关联的重要信息。

应该有一些文档说明如何处理下面的 curl 命令返回的 JSON 响应(我在经历了很大的压力之后才发现应该如何处理)。
我还在下面添加了一个用于与 API 交互的 JavaScript 代码片段,这是在收到那个认证 JSON 响应后使用的。

# 使用curl发送POST请求以获取OAuth令牌
curl --request POST \
  --url "https://auth.devcycle.com/oauth/token" \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data grant_type=client_credentials \
  --data audience=https://api.devcycle.com/ \
  --data client_id=<client id> \
  --data client_secret=<client secret>
# 在这里输入您的client id和client secret

全屏显示: 退出全屏

我创建的这个函数是用来获取API认证的,并考虑了可能出现的API和网络错误。

    /** 这个函数被定义为异步函数,这是因为尽管它没有被拒绝,`.catch` 仍然不会被调用

* 这意味着在`.then`中需要一个布尔值检查来处理错误
       */

      window.getAuthToken = async function getAuthToken(DEVCYCLE_API_CLIENT_ID, DEVCYCLE_API_CLIENT_SECRET) {
        let error;
        if(getAuthToken.expiresAt > Date.now()) return [getAuthToken.__token, error];
    /*window.providerConfig 引用了页面上的表单元素*/
        if(!(DEVCYCLE_API_CLIENT_ID = window.providerConfig.id.value)||!(DEVCYCLE_API_CLIENT_SECRET = window.providerConfig.secret.value)) return;

        return fetch("https://auth.devcycle.com/oauth/token", {
          method: "POST",
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
          body: new URLSearchParams({
            grant_type: "client_credentials",
            audience: "https://api.devcycle.com/",
            client_id: DEVCYCLE_API_CLIENT_ID,
            client_secret: DEVCYCLE_API_CLIENT_SECRET,
          }),
        }).then(res=>(res.ok || (error = `请求因 HTTP 状态 ${res.status} 失败,针对 https://auth.devcycle.com/oauth/token。`), res.json()))
        .then(json=>{
          json.error && (error &&= `${error} ${(json.error_description || '')} • ${json.error}`),
          getAuthToken.auth = json, getAuthToken.expiresAt = Date.now() + json.expires_in * 1000;
          return [getAuthToken.__token = json.access_token, error]
        }).catch(err=>{
          return [null, `无法向 \`https://auth.devcycle.com/oauth/token\` 发出请求 - 您可能已断开互联网连接 • ${err.message}`]
        })
      }

全屏模式;退出全屏模式

它这样用,这一部分实际上文档中没提到。

// 从 https://api.devcycle.com/v1/ 获取数据,使用指定的方法和头部信息,如果有body,则将其转换为JSON字符串
fetch(`https://api.devcycle.com/v1/`, {
    method: args.method,
    headers: {
      "authorization": getAuthToken.__token/** references __token for when getAuthToken gets initialized */,
      "content-type": "application/json"
    },
    ...(args.body&&{body: JSON.stringify(args.body)})
    // body: JSON.stringify({ 'description': "A learning experience on DevCycle's API" })
  }).then(res=>res.json());

全屏模式 退出全屏

这个API设计真的很棒

除了上述的麻烦外,我真的喜欢这个API的直接性,有些请求只需通过包含的HTTP动词就能直接获取或设置信息,而不需要冗长的请求体。
设计这个API的人真是行家,赞一个!

SDK文档

文档中缺少如何处理JSON变量的说明。我通过猜测才得知,默认值需要被解析成对象才能正常运作。

此外,文档还应提到,当任一 开发、测试、生产 环境的目标被禁用时,无论变量是否被定义为 true,调用 devCycleClient.variableValue 将评估传递给它的默认值。
这让我困惑了很久。

额外奖项种类

  • API高手:我充分利用了用于获取所有环境、功能和变体SDK密钥的API,包括变量名。
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消